使用PHP/Python验证ECDSA signatu

2024-10-02 02:37:10 发布

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

我编写了在Android上使用spongycastle库生成ECDSA签名的代码。然后我将符号字符串和公钥发送到服务器(Ubuntu 16.04),并尝试使用php和python验证这个符号。在

我在我的android应用程序上测试验证。效果很好。在

我使用php openssl扩展,而Python则使用ecdsa0.13。但是,这两个都失败了。我再次尝试,使用openssl命令,但它也无法验证。在

我不知道我哪里错了。在

为什么ECDSA验证失败?在


这是我的代码:

  1. 生成签名(android):

    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
    try {
        KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA","SC");
        g.initialize(spec, new SecureRandom());
        KeyPair keyPair = g.generateKeyPair();
        privateKey = keyPair.getPrivate();
        publicKey = keyPair.getPublic();
        ///write public key to pem file
        ......
        FileOutputStream fileOutputStream1 = new FileOutputStream(file1);
        StringWriter writer1 = new StringWriter();
        PemWriter pemWriter1 = new PemWriter(writer1);
        pemWriter1.writeObject(new PemObject("PUBLIC KEY",publicKey.getEncoded()));
        pemWriter1.flush();
        pemWriter1.close();
        String publickeyPem = writer1.toString();
        fileOutputStream1.write(publickeyPem.getBytes());
        fileOutputStream1.close();
        } catch (Exception e) {
            e.printStackTrace();}
        ......
        //Sign and veryfied
         String chuoi = txtChuoi.getText().toString();
         byte[] chuoiInput = chuoi.getBytes("UTF-8");
         Signature sig = Signature.getInstance("NONEwithECDSA","SC");
         sig.initSign(privateKey);
         sig.update(chuoiInput);
         ///SIGN
         byte[] signatureBytes = sig.sign()
         txtMaHoa.setText(Base64.encodeToString(signatureBytes,Base64.DEFAULT));
         sig.initVerify(publicKey);
         sig.update(chuoiInput);
         ///VERIFIED
         txtGiaiMa.setText(sig.verify(signatureBytes)+"");
         ///Write string sign in txtMahoa to file
         .......
    
  2. 我有签名和公钥的输出是:

    ^{pr2}$

    (公钥)

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEj07XEM+ulPyrdsfAf9prN2L2dNUd /Yy0rABcFdueAwYUf86f8Cc93Ws6sxzIvf2iKOapFby7EjHewjhLM/z7Qg==
     -----END PUBLIC KEY-----
    
  3. 使用PHP验证:

    $pubkeyid = openssl_pkey_get_public("/var/www/html/ca.pem");
    
    $data = "nguyen tran thanh Lam";
    
     $signature =
      "MEYCIQC7Hz631IFGsUOogcRLeN99uM9hWgLr+LGzuJvR/6nBrgIhAMXgZcvXyMRCAELXlNNS1a9jiAT1x0q2C5Mdu+2aZKtN";
    $ok = openssl_verify($data, $signature, $pubkeyid);
    if ($ok == 1) {
    echo "good";
    } elseif ($ok == 0) {
       echo "bad";
    } else {
    echo "ugly, error checking signature";
    }
    ?>
    

Tags: keynewpublicecdsasignaturesig公钥openssl
1条回答
网友
1楼 · 发布于 2024-10-02 02:37:10

Comment: ... but the verify function don't return anything. So I not sure

如果crypto.verify(...不抛出错误,这意味着Verify正常。请参阅下面的更新代码。
使用错误的证书、签名或数据进行验证。在


Comment: what do you think about add base64.b64decode. ... because in android code I have this linetxtMaHoa.setText(Base64.encodeToString(signatureBytes,Ba‌​se64.DEFAULT));

PEM已经是base64,检查上面的.setText(Base64...是否可以省略。现在我用base64.b64decode更新了下面的代码。在


Question: Example b"sha256"? "b" is a binary (built-in funtion or I must convert string sha256 to binary?)

我只能用字符串(digest-names),例如:

import pem, base64
from OpenSSL import crypto

signature  = b"MEYCIQC7Hz631IFGsUOogcRLeN99uM9hWgLr+LGzuJvR/6nBrgIhAMXgZcvXyMRCAELXlNNS1a9jiAT1x0q2C5Mdu+2aZKtN"

# As Creator of the Signatur do additional base64 encoding!
signature = base64.b64decode(signature)

data = "nguyen tran thanh Lam"

certificate = pem.parse_file('Android.pem')[0]
cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate.as_bytes())

try:
    crypto.verify(cert=cert, signature=signature, data=data, digest='sha256')
except crypto.Error as exp:
    print('crypto.Error:{}'.format(exp.args))

>>>crypto.Error:([('', 'ECDSA_do_verify', 'bad signature')],)

Note: Throws crypto.Error because not using the certificate which created the signature.


OpenSSL.crypto.verify(certificate, signature, data, digest)

Verify the signature for a data string.
certificate is a X509 instance corresponding to the private key which generated the signature.
signature is a str instance giving the signature itself.
data is a str instance giving the data to which the signature applies.
digest is a str instance naming the message digest type of the signature, for example b"sha256".

New in version 0.11.

相关问题 更多 >

    热门问题