生成公钥的代码是
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
public static Map<String, String> createKeys(int keySize){
KeyPairGenerator kpg;
try{
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
}catch(NoSuchAlgorithmException e){
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
kpg.initialize(keySize);
KeyPair keyPair = kpg.generateKeyPair();
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
Key privateKey = keyPair.getPrivate();
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
然后 key 发送给我,我想用 python importKey() 读取它。但我总是收到错误“不支持 RSA key 格式”。
关键是“MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGrLFBqubzi45M_yxs5Ps4XW3DIOeAo5x7Ca9EYmWAig3Rb3Efm2PCgipwNube2Ae5eUI5dYlQW32FSF81rw7vNdwfODDzITyWRPLEuVbBb kF5zD6kTxycqlVbH-uTyb95181jpY_XY6tmEOCZCq3mZhil9VA4ZvAoSBcJ8muXaQIDAQAB"
用 Google 搜索后,我尝试向其添加 header “-----BEGIN RSA PUBLIC KEY-----”,但没有任何不同。
最佳答案
您正在使用“URLsafe”base64 编码器,尽管不是标准的 Java 编码器。 “URLsafe”使用不同的字符(对于代码值 62 和 63),没有填充,也没有换行符。 PEM 格式(早在 URLsafe 编码出现之前就已设计,实际上是在 URL 出现之前一年多!)使用传统的 Base64 字符(现在主要与 MIME 相关)、填充和换行(每 64 个字符)。尽管并非所有软件都会检查换行符;你没有说你正在使用哪个Python加密库(有几个),所以我无法检查它是否关心这一点。
在 Java 8 中,您可以使用
Base64.getMimeEncoder()
来处理其中的大部分,但如果您坚持使用较旧的 Java(见下文)和/或其他一些库,则必须提供有关它的详细信息。您可以将- _
字符转换为+/
,将=
填充添加为 4 的倍数,然后添加如果需要的话换行。OTOH我看过的Python库接受'DER'(即二进制)以及PEM,所以你可以解码base64(许多解码器可以处理缺少填充的情况,至少有些解码器可以使用或处理两种字符集没有规范)并按原样使用。
Java 使用的公钥编码(它不准确地称为“X.509”)以及 OpenSSL 和其他一些东西使用的公钥编码是通用的,并且包含算法标识符,因此正确的 PEM标签是
-----BEGIN PUBLIC KEY-----
和-----END PUBLIC KEY-----
(没有RSA
)。你没有说你使用什么Java,但它显然默认为RSA的1024位,这已经过时了好几年,并且不再被认为能提供足够的安全裕度(尽管没有公开的报告) 但实际上打破它)。 2048 现在被广泛认为是最小值,某些应用程序或环境出于各种原因使用更多。但是,决定使用哪些加密参数(以及您的应用程序是否应该使用 RSA,如果是的话,使用哪种变体)并不是编程问题,也不是 SO 的题外话;它们属于 crypto.SX (了解基本原则)或security.SX (对于应用程序)。
关于java - 如何读取 rsa 公钥形式字符串(由 java 生成,我想用 Python 读取它),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59080895/