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

相关文章

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

PDF 软件如何帮助您编辑、转换和保护文件。

如何找到最好的 PDF 编辑器。 无论您是在为您的企业寻找更高效的 PDF 解决方案,还是尝试组织和编辑主文档,PDF 编辑器都可以在一个地方提供您需要的所有工具。市面上有很多 PDF 编辑器 — 在决定哪个最适合您时,请考虑这些因素。 1. 确定您的 PDF 文档软件需求。 不同的 PDF 文档软件程序可以具有不同的功能,因此在决定哪个是最适合您的 PDF 软件之前,请花点时间评估您的

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

Golang 网络爬虫框架gocolly/colly(五)

gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goquery就显得捉襟见肘了。解决方法有很多种: 一,最笨拙但有效的方法是字符串处理,go语言string底层对应字节数组,复制任何长度的字符串的开销都很低廉,搜索性能比较高; 二,利用正则表达式,要提取的数据往往有明显的特征,所以正则表达式写起来比较简单,不必非常严谨; 三,使

Golang网络爬虫框架gocolly/colly(四)

爬虫靠演技,表演得越像浏览器,抓取数据越容易,这是我多年爬虫经验的感悟。回顾下个人的爬虫经历,共分三个阶段:第一阶段,09年左右开始接触爬虫,那时由于项目需要,要访问各大国际社交网站,Facebook,myspace,filcker,youtube等等,国际上叫得上名字的社交网站都爬过,大部分网站提供restful api,有些功能没有api,就只能用http抓包工具分析协议,自己爬;国内的优酷、

Golang网络爬虫框架gocolly/colly(三)

熟悉了《Golang 网络爬虫框架gocolly/colly 一》和《Golang 网络爬虫框架gocolly/colly 二》之后就可以在网络上爬取大部分数据了。本文接下来将爬取中证指数有限公司提供的行业市盈率。(http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio) 定义数据结构体: type Zhj

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑