Openssl RSA:获得给定公钥的指数和模
我需要在JavaScript中使用RSA加密一些数据。周围所有的库都要求一个指数和一个模,但我从我的对手那里得到了一个Openssl RSA:获得给定公钥的指数和模,openssl,rsa,public-key,Openssl,Rsa,Public Key,我需要在JavaScript中使用RSA加密一些数据。周围所有的库都要求一个指数和一个模,但我从我的对手那里得到了一个public.key文件 如何从RSA文件中检索公共指数和模数部分?这取决于您可以使用的工具。我怀疑是否有JavaScript也可以直接在浏览器中实现这一点。这还取决于它是一次性的(总是相同的键),还是需要编写脚本 命令行/OpenSSL 如果您想在unix命令行上使用类似OpenSSL的东西,可以执行以下操作。 我假设您的public.key文件包含如下内容: -----BEG
public.key
文件
如何从RSA文件中检索公共
指数
和模数
部分?这取决于您可以使用的工具。我怀疑是否有JavaScript也可以直接在浏览器中实现这一点。这还取决于它是一次性的(总是相同的键),还是需要编写脚本
命令行/OpenSSL
如果您想在unix命令行上使用类似OpenSSL的东西,可以执行以下操作。
我假设您的public.key文件包含如下内容:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P
J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR
mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax
UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo
CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9
5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh
HQIDAQAB
-----END PUBLIC KEY-----
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
PEMReader pemReader = new PEMReader(new FileReader("file.pem"));
Object obj = pemReader.readObject();
pemReader.close();
if (obj instanceof X509Certificate) {
// Just in case your file contains in fact an X.509 certificate,
// useless otherwise.
obj = ((X509Certificate)obj).getPublicKey();
}
if (obj instanceof RSAPublicKey) {
// ... use the getters to get the BigIntegers.
}
然后,命令将是:
PUBKEY=`grep -v -- ----- public.key | tr -d '\n'`
然后,您可以查看ASN.1结构:
echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i
这应该会给你这样的东西:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P
J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR
mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax
UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo
CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9
5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh
HQIDAQAB
-----END PUBLIC KEY-----
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
PEMReader pemReader = new PEMReader(new FileReader("file.pem"));
Object obj = pemReader.readObject();
pemReader.close();
if (obj instanceof X509Certificate) {
// Just in case your file contains in fact an X.509 certificate,
// useless otherwise.
obj = ((X509Certificate)obj).getPublicKey();
}
if (obj instanceof RSAPublicKey) {
// ... use the getters to get the BigIntegers.
}
模数和公共指数位于最后一位字符串偏移量19中,因此使用-strparse
:
echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i -strparse 19
这将给出十六进制的模数和公共指数(两个整数):
如果始终使用同一个键,这可能很好,但这可能不太方便放入脚本
或者(这可能更容易放入脚本中)
JAVA
这取决于输入格式。如果它是密钥库中的X.509证书,请使用(RSAPublicKey)cert.getPublicKey()
:此对象有两个用于模数和指数的getter
如果它的格式如上所述,您可能需要使用及其PEMReader
来读取它。我没有尝试过以下代码,但这看起来或多或少像这样:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P
J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR
mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax
UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo
CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9
5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh
HQIDAQAB
-----END PUBLIC KEY-----
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
PEMReader pemReader = new PEMReader(new FileReader("file.pem"));
Object obj = pemReader.readObject();
pemReader.close();
if (obj instanceof X509Certificate) {
// Just in case your file contains in fact an X.509 certificate,
// useless otherwise.
obj = ((X509Certificate)obj).getPublicKey();
}
if (obj instanceof RSAPublicKey) {
// ... use the getters to get the BigIntegers.
}
(您也可以在C#中使用类似的BouncyCastle。)使用时,请注意模数中可能出现的前导00:
openssl rsa -pubin -inform PEM -text -noout < public.key
openssl rsa-pubin-notify PEM-text-noout
示例模数包含257个字节,而不是256个字节,这是因为00,包括它是因为98中的9看起来像一个负号。如果需要在脚本中解析ASN.1对象,有一个库: 对于数学运算,我发现jsbn很方便:
遍历ASN.1结构并提取exp/mod/subject/etc取决于您——我从来没有走那么远 主要供我自己参考,下面是如何从ssh-keygen生成的私钥中获取它的
openssl rsa -text -noout -in ~/.ssh/id_rsa
当然,这只适用于私钥。除了上述答案之外,我们还可以使用
asn1parse
获取值
$ openssl asn1parse -i -in pub0.der -inform DER -offset 24
0:d=0 hl=4 l= 266 cons: SEQUENCE
4:d=1 hl=4 l= 257 prim: INTEGER :C9131430CCE9C42F659623BDC73A783029A23E4BA3FAF74FE3CF452F9DA9DAF29D6F46556E423FB02610BC4F84E19F87333EAD0BB3B390A3EFA7FB392E935065D80A27589A21CA051FA226195216D8A39F151BD0334965551744566AD3DAEB53EBA27783AE08BAAACA406C27ED8BE614518C8CD7D14BBE7AFEBE1D8D03374DAE7B7564CF1182A7B3BA115CD9416AB899C5803388EE66FA3676750A77AC870EDA027DC95E57B9B4E864A3C98F1BA99A4726C085178EA8FC6C549BE5EDF970CCB8D8F9AEDEE3F5CFDE574327D05ED04060B2525FB6711F1D78254FF59089199892A9ECC7D4E4950E0CD2246E1E613889722D73DB56B24E57F3943E11520776BC4F
265:d=1 hl=2 l= 3 prim: INTEGER :010001
现在,为了得到这个偏移量,我们尝试默认的asn1parse
$ openssl asn1parse -i -in pub0.der -inform DER
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
我们需要得到位字符串部分,所以我们添加大小
深度0头(4)+深度1头(2+13)+容器1头(EOC)位+位字符串头(4)=24
如果将鼠标悬停在标记处,可以在以下位置更好地看到偏移
另一个惊人的资源:我设法找到了这个问题的答案,必须为此进行javascript注入才能安装atob
const atob:any = require('atob');
asn1(pem: any){
asn1parser.Enc.base64ToBuf = function (b64:any) {
return asn1parser.Enc.binToBuf(atob(b64));
};
const dertest = asn1parser.PEM.parseBlock(pem).der;
var hex = asn1parser.Enc.bufToHex(asn1parser.PEM.parseBlock(pem).der)
var buf = asn1parser.ASN1.parse(dertest);
var asn1 = JSON.stringify(asn1parser.ASN1.parse(dertest), asn1parser.ASN1._replacer, 2 );
+回答得好。查看PEMReader.java的源代码,它是一个真正的主力。它将检测和读取各种变体,并返回适当的对象。另一种可能的格式是X509EncodedKeySpec,它是由javaRSAPublicKey中的RSAPublicKey.getEncoded()返回的。getEncoded()将返回字节[]数组,该数组的内容与PEM格式的开始/结束公钥之间的内容相同,除了base64编码用于文本呈现。实际上,您可以在不使用BouncyCastle的情况下使用X509EncodedKeySpec,但您必须执行base64解码,然后使用java.security.KeyFactory来构建实际的RSAPublicKey。这是可行的,但我更喜欢使用BC。非常感谢布鲁诺。我将使用命令行版本…您可以对私钥执行类似的操作吗?得到指数了吗?谢谢(1) 您不需要自己为
openssl asn1parse
解码PEM,它可以处理PEM(这甚至是默认值);它甚至可以处理PEM主体(DER的base64带有换行符,但没有开始/结束线)。只是不要在PEM区块之外包含任何“评论”;许多其他的openssl
命令可以处理这个问题,但不是asn1parse
(2)自2012年1.47版本以来,BouncyCastle在bcpkix
notbcprov
中安装了PEMReader,自2013年1.50版本以来,它被重命名为PEMParser;对于返回X509CertificateHolder
而不是X509Certificate
的证书,对于返回SubjectPublicKeyInfo
的公钥,您找到解决方案了吗?不是针对2014年6.5以来由ssh keygen-o
生成的私钥,也不是从2018年7.8起默认(没有-m pem
)生成的私钥;那些使用OpenSSH专有格式的openssl
无法读取。OpenSSL也无法读取OpenSSH的id_xxx.pub
,但ssh-keygen-e-m pkcs8
,因为大约6.0会输出一个PEM公钥,可由OpenSSL rsa-pubin-text-noout
读取(如Bruno很久以前的回答)