我创建了一个python3应用程序来生成RSA密钥对
from Crypto.PublicKey import RSA
print("--Private Key Generate--")
key = RSA.generate(2048)
private_key = key.export_key()
file_out = open("key/private.pem", "wb")
file_out.write(private_key)
file_out.close()
print("--Public Key Generate--")
public_key = key.publickey().export_key()
file_out_1 = open("key/receiver.pem", "wb")
file_out_1.write(public_key)
file_out_1.close()
print("key Generated")
我使用python对一些数据进行签名并创建签名。还成功地使用python对其进行了验证
def sign(data):
private_key = RSA.import_key(open('key/private.pem').read())
h = SHA256.new(data)
signature = base64.b64encode(pss.new(private_key).sign(h))
print("signature generate")
verify(data,signature)
return signature
def verify(recive_Data ,signature):
public_key = RSA.import_key(open('key/receiver.pem').read())
h = SHA256.new(recive_Data)
verifier = pss.new(public_key)
try:
verifier.verify(h, base64.b64decode(signature))
print("The signature is authentic")
except (ValueError, TypeError):
print ("The signature is not authentic.")
但实际上,我的验证是在Android中实现的(min SDK 23,target SDK 29)。所以,我需要把这个验证码转换成Android。我尝试使用以下代码,但没有验证成功。需要一些专家的帮助
public class SecurityHelper {
private static String getKey(InputStream filename) throws IOException {
// Read key from file
String strKeyPEM = "";
BufferedReader br = new BufferedReader(new InputStreamReader(filename));
String line;
while ((line = br.readLine()) != null) {
strKeyPEM += line + "\n";
}
br.close();
// System.out.println(strKeyPEM);
return strKeyPEM;
}
public static PublicKey getPublicKey(InputStream filename) throws IOException, GeneralSecurityException {
String publicKeyPEM = getKey(filename);
return getPublicKeyFromString(publicKeyPEM);
}
public static PublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException {
String publicKeyPEM = key;
publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
System.out.println(publicKeyPEM);
byte[] encoded = Base64.decode(publicKeyPEM ,Base64.CRLF);
// System.out.println(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pubKey = kf.generatePublic(new X509EncodedKeySpec(encoded));
System.out.println(pubKey);
return pubKey;
}
public static boolean verify(PublicKey publicKey, String message, String signature) throws SignatureException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, InvalidAlgorithmParameterException {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initVerify(publicKey);
sign.update(message.getBytes("UTF-8"));
System.out.println(message);
return sign.verify(Base64.decode(signature,Base64.CRLF));
}
}
Python代码PSS和Android代码Pkcs#1 v1.5中使用了不同的填充,请参见以了解差异RFC 8017。将Android代码中的}
SHA256withRSA
替换为^{更新:
尽管根据Android文档,API级别23+支持^{} ,但API级别23会抛出一个
InvalidKeyException
(No provider supports the provided key
),API级别24+则会按照规定工作API级别23的一个可能的解决方法是使用BouncyCastle,然后必须将其作为依赖项包含在Android项目中(详细信息取决于IDE,例如Android Studio的here):
在添加BC提供程序之前,必须删除预安装的版本。要使用的架构是^{} (see section Signature Algorithms) :
注:SpongyCastle将是另一种可能性。在这里,不必删除预安装的BC提供程序。模式为
SHA256withRSA/PSS
相关问题 更多 >
编程相关推荐