golang将pkcs1格式的公钥转换为pkcs8格式的公钥

2023-12-21 18:48

本文主要是介绍golang将pkcs1格式的公钥转换为pkcs8格式的公钥,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在工作中遇到golang编写的sdk作为客户端,java语言编写程序作为服务器端的情况,需要使用go生成一个RSA公钥发送给服务器端,此公钥用于加密某些消息,使用的是RSAOAEP的加解密算法,该算法包含了两次哈希函数,能够防止重放攻击,个人建议两次哈希函数都采用sha256。具体互通方法我会在后续博客中更新。此文主要介绍将pkcs1格式的公钥转成pkcs8格式公钥的方法。

密钥格式

下表为常见的密码学术语:

TermDefinition
PKIPublic Key Cryptography. Public-key cryptography, or asymmetric cryptography, is any cryptographic system that uses pairs of keys: public keys which may be disseminated widely, and private keys which are known only to the owner. This accomplishes two functions: authentication, where the public key verifies that a holder of the paired private key sent the message, and encryption, where only the paired private key holder can decrypt the message encrypted with the public key.
PKCSIn cryptography, PKCS stands for “Public Key Cryptography Standards”. These are a group of public-key cryptography standards devised and published by RSA Security Inc, starting in the early 1990s. The company published the standards to promote the use of the cryptography techniques to which they had patents, such as the RSA algorithm, the Schnorr signature algorithm and several others. Though not industry standards (because the company retained control over them), some of the standards in recent years have begun to move into the “standards-track” processes of relevant standards organizations such as the IETF and the PKIX working-group.
RSARSA (Rivest-Shamir-Adleman) is one of the first public-key cryptosystems and is widely used for secure data transmission. In such a cryptosystem, the encryption key is public and it is different from the decryption key which is kept secret (private). In RSA, this asymmetry is based on the practical difficulty of the factorization of the product of two large prime numbers, the “factoring problem”. The acronym RSA is made of the initial letters of the surnames of Ron Rivest, Adi Shamir, and Leonard Adleman, who first publicly described the algorithm in 1978. Clifford Cocks, an English mathematician working for the British intelligence agency Government Communications Headquarters (GCHQ), had developed an equivalent system in 1973, but this was not declassified until 1997.A user of RSA creates and then publishes a public key based on two large prime numbers, along with an auxiliary value. The prime numbers must be kept secret. Anyone can use the public key to encrypt a message, but with currently published methods, and if the public key is large enough, only someone with knowledge of the prime numbers can decode the message feasibly. Breaking RSA encryption is known as the RSA problem. Whether it is as difficult as the factoring problem remains an open question.
Private KeyA Private Key is a secret key, used in Asymmetric Encryption. It is mathematically equivalent to a Public Key, but is kept secret. This is one half of a matching key-pair.
Public KeyA Public Key is a publicly distributed key, used in Asymmetric Encryption. It is mathematically equivalent to a Private Key, but is widely distributed. This is the other half of a matching key-pair.
PKCS#1In cryptography, PKCS #1 is the first of a family of standards called Public-Key Cryptography Standards (PKCS), published by RSA Laboratories. It provides the basic definitions of and recommendations for implementing the RSA algorithm for public-key cryptography. It defines the mathematical properties of public and private keys, primitive operations for encryption and signatures, secure cryptographic schemes, and related ASN.1 syntax representations.
PKCS#8In cryptography, PKCS #8 is a standard syntax for storing private key information. PKCS #8 is one of the family of standards called Public-Key Cryptography Standards (PKCS) created by RSA Laboratories. The latest version, 1.2, is available as RFC 5208.
Base64Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding. Each base64 digit represents exactly 6 bits of data. Three 8-bit bytes (i.e., a total of 24 bits) can therefore be represented by four 6-bit base64 digits.
DERDER (Distinguished Encoding Rules) is a restricted variant of BER for producing unequivocal transfer syntax for data structures described by ASN.1. Like CER, DER encodings are valid BER encodings. DER is the same thing as BER with all but one sender’s options removed. DER is a subset of BER providing for exactly one way to encode an ASN.1 value. DER is intended for situations when a unique encoding is needed, such as in cryptography, and ensures that a data structure that needs to be digitally signed produces a unique serialized representation. DER can be considered a canonical form of BER. For example, in BER a Boolean value of true can be encoded as any of 255 non-zero byte values, while in DER there is one way to encode a boolean value of true.
ASN.1Abstract Syntax Notation One (ASN.1) is an interface description language for defining data structures that can be serialized and deserialized in a standard, cross-platform way. It is broadly used in telecommunications and computer networking, and especially in cryptography.
PEMPEM is a de facto file format for storing and sending cryptography keys, certificates, and other data, based on a set of 1993 IETF standards defining “privacy-enhanced mail.” While the original standards were never broadly adopted, and were supplanted by PGP and S/MIME, the textual encoding they defined became very popular. The PEM format was eventually formalized by the IETF in RFC 7468.Many cryptography standards use ASN.1 to define their data structures, and Distinguished Encoding Rules (DER) to serialize those structures. Because DER produces binary output, it can be challenging to transmit the resulting files through systems, like electronic mail, that only support ASCII. The PEM format solves this problem by encoding the binary data using base64. PEM also defines a one-line header, consisting of “—–BEGIN “, a label, and “—–“, and a one-line footer, consisting of “—–END “, a label, and “—–“. The label determines the type of message encoded. Common labels include “CERTIFICATE”, “CERTIFICATE REQUEST”, and “PRIVATE KEY”. PEM data is commonly stored in files with a “.pem” suffix, a “.cer” or “.crt” suffix (for certificates), or a “.key” suffix (for public or private keys).[2] The label inside a PEM file represents the type of the data more accurately than the file suffix, since many different types of data can be saved in a “.pem” file.

参考链接:https://www.jhanley.com/security-key-pairs-and-private-public-keys/
通俗来讲,PKCS#1和PKCS#8都是公钥密码学中的标准实现,由RSA公司(拥有RSA算法专利)制定标准,设计实施。两种标准之间并不互通,需要通过字符编码来进行相互转换。网上已经有很多的私钥PKCS#1标准与PKCS#8标准互转的库,但是公钥互转的库有点少,本文主要实现了由PKCS#1标准公钥转换为PKCS#8标准公钥的方法。

具体实现

/*
* convert the pkcs1 public key to pbkcs8
*/
var BIT_STRING_TAG int = 0x03
var SEQUENCE_TAG int = 0x30
var NO_UNUSED_BITS = []byte{0x00}
var RSA_ALGORITHM_IDENTIFIER_SEQUENCE = []byte {
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
}func CreateSubjectPublicKeyInfoEncoding(pkcs1PublicKeyEncoding []byte) []byte  {subjectPublicKeyBitString := createDEREncoding(BIT_STRING_TAG, concat(NO_UNUSED_BITS, pkcs1PublicKeyEncoding))subjectPublicKeyInfoValue := concat(RSA_ALGORITHM_IDENTIFIER_SEQUENCE, subjectPublicKeyBitString)subjectPublicKeyInfoSequence := createDEREncoding(SEQUENCE_TAG, subjectPublicKeyInfoValue)return subjectPublicKeyInfoSequence
}func concat(bas ... []byte) []byte {var buf  []bytefor i := 0; i < len(bas); i++ {buf = append(buf, bas[i] ...)}return buf
}func createDEREncoding(tag int, value []byte) []byte {if tag < 0 || tag >= 0xFF {return nil}lengthEncoding := createDERLengthEncoding(len(value))var derEncodingBuf []bytederEncodingBuf = append(derEncodingBuf, createDERLengthEncoding(tag) ...)derEncodingBuf = append(derEncodingBuf, lengthEncoding ...)derEncodingBuf = append(derEncodingBuf, value ...)return derEncodingBuf
}func createDERLengthEncoding(size int) (b2 []byte) {if size <= 0x7F {res := uint8(size)b2 = append(b2, res)return b2} else if size <= 0xFF {
//X86 little-endianb2 = append(b2, uint8(0x81))var b  [2]byteb[0] = uint8(size)b[1] = uint8(size >> 8)b2 = append(b2, b[1])b2 = append(b2, b[0])return b2} else if size <= 0xFFFF {
//X86 little-endianb2 = append(b2, uint8(0x82))var b  [4]byteb[0] = uint8(size)b[1] = uint8(size >> 8)b[2] = uint8(size >> 16)b[3] = uint8(size >> 24)b2 = append(b2, b[1])b2 = append(b2, b[0])if size >> 16 == 0 {return b2}b2 = append(b2, b[3])b2 = append(b2, b[2])return b2}return nil
}

参考链接

这篇关于golang将pkcs1格式的公钥转换为pkcs8格式的公钥的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/521102

相关文章

golang中slice扩容的具体实现

《golang中slice扩容的具体实现》Go语言中的切片扩容机制是Go运行时的一个关键部分,它确保切片在动态增加元素时能够高效地管理内存,本文主要介绍了golang中slice扩容的具体实现,感兴趣... 目录1. 切片扩容的触发append 函数的实现2. runtime.growslice 函数gro

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Golang interface{}的具体使用

《Golanginterface{}的具体使用》interface{}是Go中可以表示任意类型的空接口,本文主要介绍了Golanginterface{}的具体使用,具有一定的参考价值,感兴趣的可以了... 目录一、什么是 interface{}?定义形China编程式:二、interface{} 有什么特别的?✅

Ubuntu上手动安装Go环境并解决“可执行文件格式错误”问题

《Ubuntu上手动安装Go环境并解决“可执行文件格式错误”问题》:本文主要介绍Ubuntu上手动安装Go环境并解决“可执行文件格式错误”问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录一、前言二、系统架构检测三、卸载旧版 Go四、下载并安装正确版本五、配置环境变量六、验证安装七、常见

Python将字符串转换为小写字母的几种常用方法

《Python将字符串转换为小写字母的几种常用方法》:本文主要介绍Python中将字符串大写字母转小写的四种方法:lower()方法简洁高效,手动ASCII转换灵活可控,str.translate... 目录一、使用内置方法 lower()(最简单)二、手动遍历 + ASCII 码转换三、使用 str.tr

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

使用Java将实体类转换为JSON并输出到控制台的完整过程

《使用Java将实体类转换为JSON并输出到控制台的完整过程》在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用JSON格式,用Java将实体类转换为J... 在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用j

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

C语言中的常见进制转换详解(从二进制到十六进制)

《C语言中的常见进制转换详解(从二进制到十六进制)》进制转换是计算机编程中的一个常见任务,特别是在处理低级别的数据操作时,C语言作为一门底层编程语言,在进制转换方面提供了灵活的操作方式,今天,我们将深... 目录1、进制基础2、C语言中的进制转换2.1 从十进制转换为其他进制十进制转二进制十进制转八进制十进

Pandas进行周期与时间戳转换的方法

《Pandas进行周期与时间戳转换的方法》本教程将深入讲解如何在pandas中使用to_period()和to_timestamp()方法,完成时间戳与周期之间的转换,并结合实际应用场景展示这些方法的... 目录to_period() 时间戳转周期基本操作应用示例to_timestamp() 周期转时间戳基