这是我的服务器公钥:
UlNBMQAIAAADAAAAAAEAAAAAAAAAAAAAAQABupDgHg710Jh4QwJriIdrY+6yyZme0e0FSQ1EFO3JEmiT+DXRLgU7CcgqGqLhosqYV7Rm1/H0I0ugFBk4zisPbgIb3epyMCcjnTgknRYddtIl9jNS8Z91/1SJ5bY0FkIRFJLHSCEcu1Un09w+gpWRoeAhSc87EMGngUZixAcyoDeYsW0mM1IlH44flo76wXERadmtAd9KFN0nYTjMwkIDyc5B9I2zvSjOQ+p54+6dl6o6nOalCWJg8V137ZMwQCk/4Tmp4C52d0AzYjEeU9gQowkrm7DgjLthd4ew/kY5a/8JfsWMJhajDPgzBV5fFJMbNL1h0fmtG8QpH5OtWukDhQ==
和加密代码:
byte[] publicBytes = Base64.decode(PUBLIC_KEY, Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA"); //or try with "RSA"
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
encrypted = cipher.doFinal(txt.getBytes());
encoded = Base64.encodeToString(encrypted, Base64.DEFAULT);
尝试加密时出现此错误:
java.security.spec.InvalidKeySpecException:java.lang.RuntimeException:错误:0D0680A8:asn1编码例程:ASN1_CHECK_TLEN:错误的标记
这是怎么了?
如前所述,这是公用RSA密钥的专有Microsoft格式BCRYPT_RSAPUBLIC_BLOB
:
BCRYPT_RSAKEY_BLOB
PublicExponent[cbPublicExp] // Big-endian.
Modulus[cbModulus] // Big-endian.
与
typedef struct _BCRYPT_RSAKEY_BLOB {
ULONG Magic; // identifies the type, e.g. BCRYPT_RSAPUBLIC_MAGIC for an RSA public key
ULONG BitLength; // size, in bits, of the key
ULONG cbPublicExp; // size, in bytes, of the exponent of the key
ULONG cbModulus; // size, in bytes, of the modulus of the key
ULONG cbPrime1; // size, in bytes, of the first prime number of the key. This is only used for private key BLOBs
ULONG cbPrime2; // size, in bytes, of the second prime number of the key. This is only used for private key BLOBs
} BCRYPT_RSAKEY_BLOB;
中的值BCRYPT_RSAKEY_BLOB
具有小端格式,指数和模数为大端格式。BCRYPT_RSAPUBLIC_MAGIC
具有826364754
或0x31415352
大端和0x52534131
小端的值。后者对应于字符串RSA1的ASCII编码。
发布的密钥是在Base64解码后以十六进制格式进行的:
525341310008000003000000000100000000000000000000010001ba90e01e0ef5d0987843026b88876b63eeb2c9999ed1ed05490d4414edc9126893f835d12e053b09c82a1aa2e1a2ca9857b466d7f1f4234ba0141938ce2b0f6e021bddea723027239d38249d161d76d225f63352f19f75ff5489e5b6341642111492c748211cbb5527d3dc3e829591a1e02149cf3b10c1a7814662c40732a03798b16d263352251f8e1f968efac1711169d9ad01df4a14dd276138ccc24203c9ce41f48db3bd28ce43ea79e3ee9d97aa3a9ce6a5096260f15d77ed933040293fe139a9e02e7677403362311e53d810a3092b9bb0e08cbb617787b0fe46396bff097ec58c2616a30cf833055e5f14931b34bd61d1f9ad1bc4291f93ad5ae90385
或分为各个部分:
little endian big endian
52534131 0x31415352
00080000 0x0800 = 2048 bits
03000000 0x 03 = 3 bytes
00010000 0x0100 = 256 bytes
00000000
00000000
big endian
010001
ba90e01e0ef5d0987843026b88876b63eeb2c9999ed1ed05490d4414edc9126893f835d12e053b09c82a1aa2e1a2ca9857b466d7f1f4234ba0141938ce2b0f6e021bddea723027239d38249d161d76d225f63352f19f75ff5489e5b6341642111492c748211cbb5527d3dc3e829591a1e02149cf3b10c1a7814662c40732a03798b16d263352251f8e1f968efac1711169d9ad01df4a14dd276138ccc24203c9ce41f48db3bd28ce43ea79e3ee9d97aa3a9ce6a5096260f15d77ed933040293fe139a9e02e7677403362311e53d810a3092b9bb0e08cbb617787b0fe46396bff097ec58c2616a30cf833055e5f14931b34bd61d1f9ad1bc4291f93ad5ae90385
最后两部分是指数:
0x010001 = 65537
和模数
0xba90e01e0ef5d0987843026b88876b63eeb2c9999ed1ed05490d4414edc9126893f835d12e053b09c82a1aa2e1a2ca9857b466d7f1f4234ba0141938ce2b0f6e021bddea723027239d38249d161d76d225f63352f19f75ff5489e5b6341642111492c748211cbb5527d3dc3e829591a1e02149cf3b10c1a7814662c40732a03798b16d263352251f8e1f968efac1711169d9ad01df4a14dd276138ccc24203c9ce41f48db3bd28ce43ea79e3ee9d97aa3a9ce6a5096260f15d77ed933040293fe139a9e02e7677403362311e53d810a3092b9bb0e08cbb617787b0fe46396bff097ec58c2616a30cf833055e5f14931b34bd61d1f9ad1bc4291f93ad5ae90385
在Java中,可以使用类创建公共密钥RSAPublicKeySpec
。此类具有一个期望指数和模数的构造函数,请参见此处和此处。
更新:
如@Maarten Bodewes的评论中所述,创建模数和指数时必须考虑以下内容BigInteger
:模数和指数为正值。但是,Java使用2的补码表示整数,因此第一个字节还包含有关符号的信息(即,如果最左边的字节大于0x79
,则该值为负)。考虑到这一点,0x00
如果最左边的字节大于,则可以添加一个字节0x79
。或者,有相应的构造函数,例如BigInteger(String val, int radix)
,如果数据以十六进制字符串形式可用(在string
-parameter 中将符号考虑为可选的+
/ -
),或者BigInteger(int signum, byte[] magnitude)
,如果数据可作为字节数组使用(- int
参数中考虑了符号)。由于在当前情况下,数据可能以十六进制字符串形式提供,因此以下内容适用(例如,模数):
BigInteger modulus = new BigInteger("ba90e01e...5ae90385", 16);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句