Go Crypto库创建的PKCS1公共密钥与“ OpenSSL RSA ...”之间的差异
我尝试使用GO的RSA和X509软件包生成一对编码私钥的PKCS8编码的私钥和相应的PKCS1公共密钥。我想具有与OpenSL命令相同的行为:
$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
$ openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
我在下面添加了GO实现,归结为必需品。 要使用它,我首先生成一个带有GeneratePrivateKey的私钥(末尾附加的示例的位大小为2048),然后用以下两种方法对私钥和公共密钥进行编码。
但是,当运行第二个OPENSL命令以编码由我的GO实现编码的私有密钥上的公共密钥时,公共键也有所不同(我包含了下面差异的示例)。特别是,OpenSL输出看起来像是通过前缀扩展了我的GO实现的输出。
我将感谢任何解释差异的解释(在最好的情况下,如何修复代码)。非常感谢!
我的GO代码如下:
package xyz
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
)
func GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
return nil, err
}
err = privateKey.Validate()
if err != nil {
return nil, err
}
return privateKey, nil
}
func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) (string, error) {
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
return "", err
}
privateBlock := pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: privateDER,
}
privatePEM := pem.EncodeToMemory(&privateBlock)
return string(privatePEM), nil
}
func EncodePublicKeyToPEM(privateKey *rsa.PrivateKey) string {
publicRsaKey := x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)
publicKeyBytes := pem.EncodeToMemory(
&pem.Block{
Type: "PUBLIC KEY",
Bytes: publicRsaKey,
})
return string(publicKeyBytes)
}
一个示例性的私钥:
-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDnT3OOrKW+S2m4
3fMyl3BjCxnZ2n39wlnYqunYSor5S8wlynhPc72tY8xmTVGhxBYul9LAXyO1/LLU
4cNARmHtSSmeUeYLCU3PMKP795oL4k/YPLqnracIyieN5s8JnmWGtqZo7hyysvhu
Yp0LDmJcQRpB3BoDyTs++/amRP5fnRkkoFABqIejbJEgsjmfXlRnjLR8H4cK8Dmp
5tm2QzSAWos/E3LV/yhhe4b0oTqxGf+lHC5i4FgPd4Co/oaq47QOQkqarxFd57DH
yKNQF3vbGJmVucFnHC+7l4QflcP2Kp/6WJL7IDXA5FC1CFLC5YCmT1pxog/0iPJb
bOiMC1KHAgMBAAECggEBANrJru7j5L3zDOP8o/1VestkA6apYQS2YU9sklWwZHVb
OZUBRv0359Bqljqppa4SED0wA/tLwjZv+CMeDBXuvM+5pTEIHESSH1P7mRBKah4V
iRpqjs7tlRHeTL2O9IQPm85pU0vq9aAdYpjek9aSW30RYymqa7zrCSwRHYK1vblm
zbGUpz3PQp5Mp/CPPBGW2arK5Syo25AJ9YphaWAKub+NXPRZTIVZFylvDtONQmwt
D8YknEPB9eQcgL41egW+ViOs7WOpB6qM8nvbNa+lvdGawog0cZefeNw0PyHxQmhB
Mt/VzvbFaqG2aeH73Na+oFX9/DuQxrvns126R42VK4kCgYEA9lkqUWvVSq8MBb+h
QLZKlSlJiJ1R/nmYqd98r7DCZYwNTRF4LqK0DUbHJCF0WJ3G0UxuKNc98+k3JVz+
5YiZMj6S660XYgQR62GaGKLiVUQmFrKCYUmLrpgDse/pvnA6BfM6MMwR/eIlitGn
B65QarKMwRphCIRrVXnViFs/QNsCgYEA8F91NvVxk14cQPBzdeHK5Z1E+ekHLQHU
nvdWpuqF4n/UWrQg4JI9ACjZIbEd5oJRkQa7M8KXonaQwFlqTe9Ov7MrMon4/CmC
l+XxBLMIb5Pif+biNle3Jhdk6N7H16S9w4PpyaT4nSCU7HNHVIbb+yjr2awKzMSH
yKi51VYKXsUCgYBMGW1GK65+3KY1HGZezDEr9M4fYqHSn5N2XnBxAYR7xBDTzuK2
XVKLi2K3GZKMUWj6fMbG3P7pWxDK/PhMxa61Y7kVDqpbf/BdKxBkLeUG+/9cIZa/
IO4CaDkz/W3Sg26ZKfK+4jtolzSLtooHiGSVIUTz3gc9j1Js3C8HaVCX4wKBgA2b
eck4r8tF4peShRbBR3kkJAl5tZxIpD6zhcZBNH8T+XOBCvNrk+R0a4ZKvoSUEAYD
uYk+lNLvn1YkOa5bw7t6axGbWer8dpYewDwh3nJijsnqyheFc6rGXEIKiomcm9l7
mDqACkrq00NnazxPvhhDwsY5xQq+fWlQk+SN0Fx5AoGAKIMHfXkYrObD8NxE4kvs
Knx3/aH2vAAsDbC+mA2wZOSZ+hsD3SO62ypI3UW3Fxn5+55sQMsMCqaOJBXrLZMh
2iyTMk7V5Bx+//+pa5Hv3yPmDeGtlAT+gbwaqrh5KM1eaW1TVZ1HdUNmamh9Iq0O
KrEPYf2r8+IjAhctV08Mx7I=
-----END RSA PRIVATE KEY-----
由我的GO实现编码的公共密钥:
-----BEGIN PUBLIC KEY-----
MIIBCgKCAQEA509zjqylvktpuN3zMpdwYwsZ2dp9/cJZ2Krp2EqK+UvMJcp4T3O9
rWPMZk1RocQWLpfSwF8jtfyy1OHDQEZh7UkpnlHmCwlNzzCj+/eaC+JP2Dy6p62n
CMonjebPCZ5lhramaO4csrL4bmKdCw5iXEEaQdwaA8k7Pvv2pkT+X50ZJKBQAaiH
o2yRILI5n15UZ4y0fB+HCvA5qebZtkM0gFqLPxNy1f8oYXuG9KE6sRn/pRwuYuBY
D3eAqP6GquO0DkJKmq8RXeewx8ijUBd72xiZlbnBZxwvu5eEH5XD9iqf+liS+yA1
wORQtQhSwuWApk9acaIP9IjyW2zojAtShwIDAQAB
-----END PUBLIC KEY-----
第二个OpenSSL命令生成的公共密钥(请注意,仅与前面的miibijanbgkqhkqhkig9w0baqefaocaocaocaocaocac8a )
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA509zjqylvktpuN3zMpdw
YwsZ2dp9/cJZ2Krp2EqK+UvMJcp4T3O9rWPMZk1RocQWLpfSwF8jtfyy1OHDQEZh
7UkpnlHmCwlNzzCj+/eaC+JP2Dy6p62nCMonjebPCZ5lhramaO4csrL4bmKdCw5i
XEEaQdwaA8k7Pvv2pkT+X50ZJKBQAaiHo2yRILI5n15UZ4y0fB+HCvA5qebZtkM0
gFqLPxNy1f8oYXuG9KE6sRn/pRwuYuBYD3eAqP6GquO0DkJKmq8RXeewx8ijUBd7
2xiZlbnBZxwvu5eEH5XD9iqf+liS+yA1wORQtQhSwuWApk9acaIP9IjyW2zojAtS
hwIDAQAB
-----END PUBLIC KEY-----
I try to generate a pair of a PKCS8 encoded private key and the corresponding PKCS1 encoded public key using the rsa and x509 packages of Go. I want to have the same behavior as the openssl commands below:
$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
$ openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
I have added my Go implementation below, boiled down to the essentials.
To use it, I first generate a private key with GeneratePrivateKey (with bit size 2048 for the example attached on the end), and then encode the private key and the public key with the following two methods.
However, when running the second openssl command to encode the public key on the private key encoded by my Go implementation, the public keys differ (I included an example for the difference below). In particular, it looks as if the openssl output extends the output of my Go implementation by a prefix.
I would be grateful for any explaination of the difference (and in the best case, how I can fix my code). Thank you very much!
My Go code looks as follows:
package xyz
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
)
func GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
return nil, err
}
err = privateKey.Validate()
if err != nil {
return nil, err
}
return privateKey, nil
}
func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) (string, error) {
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
return "", err
}
privateBlock := pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: privateDER,
}
privatePEM := pem.EncodeToMemory(&privateBlock)
return string(privatePEM), nil
}
func EncodePublicKeyToPEM(privateKey *rsa.PrivateKey) string {
publicRsaKey := x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)
publicKeyBytes := pem.EncodeToMemory(
&pem.Block{
Type: "PUBLIC KEY",
Bytes: publicRsaKey,
})
return string(publicKeyBytes)
}
An exemplary private key:
-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDnT3OOrKW+S2m4
3fMyl3BjCxnZ2n39wlnYqunYSor5S8wlynhPc72tY8xmTVGhxBYul9LAXyO1/LLU
4cNARmHtSSmeUeYLCU3PMKP795oL4k/YPLqnracIyieN5s8JnmWGtqZo7hyysvhu
Yp0LDmJcQRpB3BoDyTs++/amRP5fnRkkoFABqIejbJEgsjmfXlRnjLR8H4cK8Dmp
5tm2QzSAWos/E3LV/yhhe4b0oTqxGf+lHC5i4FgPd4Co/oaq47QOQkqarxFd57DH
yKNQF3vbGJmVucFnHC+7l4QflcP2Kp/6WJL7IDXA5FC1CFLC5YCmT1pxog/0iPJb
bOiMC1KHAgMBAAECggEBANrJru7j5L3zDOP8o/1VestkA6apYQS2YU9sklWwZHVb
OZUBRv0359Bqljqppa4SED0wA/tLwjZv+CMeDBXuvM+5pTEIHESSH1P7mRBKah4V
iRpqjs7tlRHeTL2O9IQPm85pU0vq9aAdYpjek9aSW30RYymqa7zrCSwRHYK1vblm
zbGUpz3PQp5Mp/CPPBGW2arK5Syo25AJ9YphaWAKub+NXPRZTIVZFylvDtONQmwt
D8YknEPB9eQcgL41egW+ViOs7WOpB6qM8nvbNa+lvdGawog0cZefeNw0PyHxQmhB
Mt/VzvbFaqG2aeH73Na+oFX9/DuQxrvns126R42VK4kCgYEA9lkqUWvVSq8MBb+h
QLZKlSlJiJ1R/nmYqd98r7DCZYwNTRF4LqK0DUbHJCF0WJ3G0UxuKNc98+k3JVz+
5YiZMj6S660XYgQR62GaGKLiVUQmFrKCYUmLrpgDse/pvnA6BfM6MMwR/eIlitGn
B65QarKMwRphCIRrVXnViFs/QNsCgYEA8F91NvVxk14cQPBzdeHK5Z1E+ekHLQHU
nvdWpuqF4n/UWrQg4JI9ACjZIbEd5oJRkQa7M8KXonaQwFlqTe9Ov7MrMon4/CmC
l+XxBLMIb5Pif+biNle3Jhdk6N7H16S9w4PpyaT4nSCU7HNHVIbb+yjr2awKzMSH
yKi51VYKXsUCgYBMGW1GK65+3KY1HGZezDEr9M4fYqHSn5N2XnBxAYR7xBDTzuK2
XVKLi2K3GZKMUWj6fMbG3P7pWxDK/PhMxa61Y7kVDqpbf/BdKxBkLeUG+/9cIZa/
IO4CaDkz/W3Sg26ZKfK+4jtolzSLtooHiGSVIUTz3gc9j1Js3C8HaVCX4wKBgA2b
eck4r8tF4peShRbBR3kkJAl5tZxIpD6zhcZBNH8T+XOBCvNrk+R0a4ZKvoSUEAYD
uYk+lNLvn1YkOa5bw7t6axGbWer8dpYewDwh3nJijsnqyheFc6rGXEIKiomcm9l7
mDqACkrq00NnazxPvhhDwsY5xQq+fWlQk+SN0Fx5AoGAKIMHfXkYrObD8NxE4kvs
Knx3/aH2vAAsDbC+mA2wZOSZ+hsD3SO62ypI3UW3Fxn5+55sQMsMCqaOJBXrLZMh
2iyTMk7V5Bx+//+pa5Hv3yPmDeGtlAT+gbwaqrh5KM1eaW1TVZ1HdUNmamh9Iq0O
KrEPYf2r8+IjAhctV08Mx7I=
-----END RSA PRIVATE KEY-----
The public key as encoded by my Go implementation:
-----BEGIN PUBLIC KEY-----
MIIBCgKCAQEA509zjqylvktpuN3zMpdwYwsZ2dp9/cJZ2Krp2EqK+UvMJcp4T3O9
rWPMZk1RocQWLpfSwF8jtfyy1OHDQEZh7UkpnlHmCwlNzzCj+/eaC+JP2Dy6p62n
CMonjebPCZ5lhramaO4csrL4bmKdCw5iXEEaQdwaA8k7Pvv2pkT+X50ZJKBQAaiH
o2yRILI5n15UZ4y0fB+HCvA5qebZtkM0gFqLPxNy1f8oYXuG9KE6sRn/pRwuYuBY
D3eAqP6GquO0DkJKmq8RXeewx8ijUBd72xiZlbnBZxwvu5eEH5XD9iqf+liS+yA1
wORQtQhSwuWApk9acaIP9IjyW2zojAtShwIDAQAB
-----END PUBLIC KEY-----
The public key as generated by the second openssl command (note that it only differs from the former by the prefix MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
)
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA509zjqylvktpuN3zMpdw
YwsZ2dp9/cJZ2Krp2EqK+UvMJcp4T3O9rWPMZk1RocQWLpfSwF8jtfyy1OHDQEZh
7UkpnlHmCwlNzzCj+/eaC+JP2Dy6p62nCMonjebPCZ5lhramaO4csrL4bmKdCw5i
XEEaQdwaA8k7Pvv2pkT+X50ZJKBQAaiHo2yRILI5n15UZ4y0fB+HCvA5qebZtkM0
gFqLPxNy1f8oYXuG9KE6sRn/pRwuYuBYD3eAqP6GquO0DkJKmq8RXeewx8ijUBd7
2xiZlbnBZxwvu5eEH5XD9iqf+liS+yA1wORQtQhSwuWApk9acaIP9IjyW2zojAtS
hwIDAQAB
-----END PUBLIC KEY-----
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
OPENSL语句在PKCS#8格式中生成一个私钥,并以X.509/SPKI格式的公共密钥进行了PEM编码。
使用GO代码生成的私钥具有PKCS#8格式,但是PEM编码使用错误的标头和页脚(正确的标题和页脚将为 ------开始私有密钥------- 和 -----结束私钥------ )。修复程序是在
encodeprivateKeyTopem()
中调整pem.block()
相应地调用类型(类型:“ private键”
)。对于使用GO代码生成的公共密钥,情况是相反的:此处,标题和页脚对应于PEM编码的X.509/SPKKI密钥的标题。但是,身体是PKCS#1格式。这就是钥匙有所不同的原因。修复程序是在
encodepublicKeyTopem()
中使用X.509/SPKI格式而不是MARSHALPKCS1PUBLICKEYKEKEY()
mashalpkixpublickey()。顺便说一句,检查密钥的最佳方法是使用ASN.1解析器,例如 https:// lapo。它/asn1js/。
The OpenSSL statements generate a private key in PKCS#8 format and a public key in X.509/SPKI format, both PEM encoded.
The private key generated with the Go Code has the PKCS#8 format, but the PEM encoding uses the wrong header and footer (correct would be -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----). The fix is to adjust in
EncodePrivateKeyToPEM()
in thepem.Block()
call the type accordingly (Type: "PRIVATE KEY"
).In the case of the public key generated with the Go Code, the situation is reversed: Here, the header and footer correspond to those of a PEM encoded X.509/SPKI key. However, the body is PKCS#1 formatted. This is the reason why the keys differ. The fix is to use in
EncodePublicKeyToPEM()
the methodMarshalPKIXPublicKey()
for the X.509/SPKI format instead ofMarshalPKCS1PublicKey()
.By the way, the best way to inspect the keys is to use an ASN.1 parser, e.g. https://lapo.it/asn1js/.