如何读取 rsa public 密钥形式字符串(由 java 生成,我想用 Python 读取它)
How can I read a rsa public key form string(Generate by java and I want to read it with Python)
生成 public 密钥的代码是
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;
}
密钥然后发送给我,我想用 python importKey() 读取它。但我总是得到错误 "RSA key format is not supported".
关键是"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGrLFBqubzi45M_yxs5Ps4XW3DIOeAo5x7Ca9EYmWAig3Rb3Efm2PCgipwNube2Ae5eUI5dYlQW32FSF81rw7vNdwfODDzITyWRPLEuVbBbkF5zD6kTxycqlVbH-uTyb95181jpY_XY6tmEOCZCq3mZhil9VA4ZvAoSBcJ8muXaQIDAQAB"
用 Google 搜索后,我尝试添加 header "-----BEGIN RSA PUBLIC KEY-----" 并没有什么不同.
您正在使用 'URLsafe' base64 编码器,尽管不是标准的 Java 编码器。 'URLsafe' 使用不同的字符(代码值 62 和 63)并且没有填充,也没有换行符。 PEM 格式(早在 URLsafe 编码出现之前就设计了,实际上比 URL 出现早了一年!)使用传统的 base64 字符(现在主要与 MIME 相关联)、填充和换行符(每 64 个字符)。尽管并非所有软件 检查 换行符;你没有说你正在使用哪个 Python 加密库(有几个)所以我无法检查它是否关心这一点。
在 Java 8 up 你可以使用 Base64.getMimeEncoder()
来处理其中的大部分,但如果你被困在旧的 Java (见下文) and/or 一些其他图书馆,你必须提供有关它的详细信息。您 可以 将 - _
字符转换为 + /
,将 =
填充添加到 4 的倍数,并根据需要添加换行符。
OTOH 我看过的 Python 库接受 'DER' (即二进制)以及 PEM,所以你可以只解码 base64(许多解码器可以处理缺少填充和在至少有些可以处理有或没有规范的字符集)并按原样使用它。
Java(它不准确地称为 "X.509"
)以及 OpenSSL 和其他一些东西使用的公钥编码是通用的,包括一个算法标识符,所以正确的PEM 标签是 -----BEGIN PUBLIC KEY-----
和 ------END PUBLIC KEY-----
(否 RSA
)。
你不说你用什么Java,但它显然默认为 RSA 的 1024 位,它已经过时好几年了,不再被认为可以提供足够的安全性保证金(虽然没有公开报告 yet 实际上 breaking 它)。 2048 现在被广泛认为是最小值,一些应用程序或环境出于各种原因使用更多。但是决定使用什么加密参数(实际上你的应用程序是否应该使用 RSA,如果是的话是哪个变体)不是编程问题,也不是 SO 的主题;它们属于 crypto.SX (for the underlying principles) or security.SX(对于应用程序)。
生成 public 密钥的代码是
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;
}
密钥然后发送给我,我想用 python importKey() 读取它。但我总是得到错误 "RSA key format is not supported".
关键是"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGrLFBqubzi45M_yxs5Ps4XW3DIOeAo5x7Ca9EYmWAig3Rb3Efm2PCgipwNube2Ae5eUI5dYlQW32FSF81rw7vNdwfODDzITyWRPLEuVbBbkF5zD6kTxycqlVbH-uTyb95181jpY_XY6tmEOCZCq3mZhil9VA4ZvAoSBcJ8muXaQIDAQAB"
用 Google 搜索后,我尝试添加 header "-----BEGIN RSA PUBLIC KEY-----" 并没有什么不同.
您正在使用 'URLsafe' base64 编码器,尽管不是标准的 Java 编码器。 'URLsafe' 使用不同的字符(代码值 62 和 63)并且没有填充,也没有换行符。 PEM 格式(早在 URLsafe 编码出现之前就设计了,实际上比 URL 出现早了一年!)使用传统的 base64 字符(现在主要与 MIME 相关联)、填充和换行符(每 64 个字符)。尽管并非所有软件 检查 换行符;你没有说你正在使用哪个 Python 加密库(有几个)所以我无法检查它是否关心这一点。
在 Java 8 up 你可以使用
Base64.getMimeEncoder()
来处理其中的大部分,但如果你被困在旧的 Java (见下文) and/or 一些其他图书馆,你必须提供有关它的详细信息。您 可以 将- _
字符转换为+ /
,将=
填充添加到 4 的倍数,并根据需要添加换行符。OTOH 我看过的 Python 库接受 'DER' (即二进制)以及 PEM,所以你可以只解码 base64(许多解码器可以处理缺少填充和在至少有些可以处理有或没有规范的字符集)并按原样使用它。
Java(它不准确地称为
"X.509"
)以及 OpenSSL 和其他一些东西使用的公钥编码是通用的,包括一个算法标识符,所以正确的PEM 标签是-----BEGIN PUBLIC KEY-----
和------END PUBLIC KEY-----
(否RSA
)。你不说你用什么Java,但它显然默认为 RSA 的 1024 位,它已经过时好几年了,不再被认为可以提供足够的安全性保证金(虽然没有公开报告 yet 实际上 breaking 它)。 2048 现在被广泛认为是最小值,一些应用程序或环境出于各种原因使用更多。但是决定使用什么加密参数(实际上你的应用程序是否应该使用 RSA,如果是的话是哪个变体)不是编程问题,也不是 SO 的主题;它们属于 crypto.SX (for the underlying principles) or security.SX(对于应用程序)。