需要将以下python代码转换为Android吗?

2024-10-03 23:26:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个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));
    }


}

Tags: keynewstringreturnprivatepublicoutrsa
1条回答
网友
1楼 · 发布于 2024-10-03 23:26:45

Python代码PSS和Android代码Pkcs#1 v1.5中使用了不同的填充,请参见以了解差异RFC 8017。将Android代码中的SHA256withRSA替换为^{}

更新:

尽管根据Android文档,API级别23+支持^{},但API级别23会抛出一个InvalidKeyExceptionNo provider supports the provided key),API级别24+则会按照规定工作

API级别23的一个可能的解决方法是使用BouncyCastle,然后必须将其作为依赖项包含在Android项目中(详细信息取决于IDE,例如Android Studio的here):

implementation 'org.bouncycastle:bcprov-jdk15on:1.64'

在添加BC提供程序之前,必须删除预安装的版本。要使用的架构是^{} (see section Signature Algorithms)

Security.removeProvider("BC"); 
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
Signature sign = Signature.getInstance("SHA256withRSAandMGF1"); 
// Go ahead as for schema SHA256withRSA/PSS...

注:SpongyCastle将是另一种可能性。在这里,不必删除预安装的BC提供程序。模式为SHA256withRSA/PSS

相关问题 更多 >