Android / Python如何使用RSA和PKCS1填充来验证签名SHA256

丛海

我是新成员,我已经等了两天才能找到解决方案,以验证从android客户端到python服务器的签名。首先,我创建密钥对并从私钥生成签名。谢谢pedrofb我已经更新了完整代码。验证在python服务器中完成。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    KeyPairGenerator keyPairGenerator = null;
    try {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        //keyStore.deleteEntry("key1");
        keyPairGenerator = KeyPairGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
        try {
            KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("key1", KeyProperties.PURPOSE_SIGN)
                    .setKeySize(2048)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setDigests(KeyProperties.DIGEST_SHA256)
                    .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
            keyPairGenerator.initialize(builder.build());
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
        PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
        String publicKeyStr = Base64.encodeToString(publicKey.getEncoded(), Base64.NO_WRAP);
        Log.d("Hahaha", publicKeyStr);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        String data = "haha";
        signature.update(data.getBytes());
        byte[] signatureBytes = signature.sign();
        String signatureBase64 = Base64.encodeToString(signatureBytes, Base64.NO_WRAP);
        Log.d("Hahaha", signatureBase64);
        Signature verifySignature = Signature.getInstance("SHA256withRSA");
        verifySignature.initVerify(publicKey);
        verifySignature.update(data.getBytes());
        boolean isVerify = verifySignature.verify(Base64.decode(signatureBase64, Base64.NO_WRAP));
        Log.d("Hahaha", isVerify + "");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static String sha256(String rawString){
    MessageDigest shaDigest;
    byte[] data;
    try {
        data = rawString.getBytes("UTF-8");
        shaDigest = MessageDigest.getInstance("SHA-256");
    } catch (Exception e) {
        return null;
    }
    shaDigest.update(data);
    return toHex(shaDigest.digest());
}

public static String toHex(byte[] tmp) {
    char hexDigits[] =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
                    'e', 'f'};
    int nBytesLen = tmp.length;
    char str[] = new char[nBytesLen * 2];
    int k = 0;
    for (byte byte0 : tmp) {
        str[k++] = hexDigits[byte0 >>> 4 & 0xf];
        str[k++] = hexDigits[byte0 & 0xf];
    }
    return new String(str);
}

和服务器,我PKCS1_v1_5用来验证签名,它将从android客户端发送

from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from base64 import b64decode

keyDER = b64decode(open('public.der').read())
key = RSA.importKey(keyDER)
message = "haha"
h = SHA256.new(message)
print h.hexdigest()
signature = b64decode(open('signature.der').read())
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
    print "The signature is authentic."
else:
    print "The signature is not authentic."

我有检查数据散列客户端和服务器,这是一样的,但verifier.verify返回假的,public.der是可变的价值PublicKeyStrsignature.der为变量的值SignatureBase64,请帮助我。

佩德罗夫

[已解决注释]您的Java代码中有几个错误

1)在Java代码中,您将使用SHA256两次消化消息并签名一个十六进制值,而不是二进制消息。

在Java中,SHA256withRSA执行若干操作,首先对消息应用SHA256摘要算法,然后对RSA PKCS#1 v1.5算法应用。在python(或其他语言)中,可以通过以下两个步骤以编程方式完成

更改

signature.update(sha256(data).getBytes());
verifySignature.update(sha256(data).getBytes());

signature.update(data.getBytes());
verifySignature.update(data.getBytes());

2)拆下.setBlockModes(KeyProperties.BLOCK_MODE_CBC)这是加密参数,不适用于数字签名

3)您应该一次创建密钥对,而不是每次onCreate都调用

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章