使用PHP/Python验证ECDSA签名

使用PHP/Python验证ECDSA签名,php,android,python,php-openssl,boringssl,Php,Android,Python,Php Openssl,Boringssl,我编写了使用spongycastle库在Android上生成ECDSA签名的代码。然后我将符号字符串和公钥发送到服务器(Ubuntu 16.04),并尝试使用php和python来验证这个符号 我在android应用程序上进行测试验证。它工作得很好 我使用php openssl扩展,Python使用ecdsa 0.13。但是,这两项都失败了。我再次尝试,使用openssl命令,但它也无法验证 我不知道,我错在哪里 为什么ECDSA验证失败 这是我的密码: 生成签名(android): 我有签

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

我在android应用程序上进行测试验证。它工作得很好

我使用php openssl扩展,Python使用ecdsa 0.13。但是,这两项都失败了。我再次尝试,使用openssl命令,但它也无法验证

我不知道,我错在哪里

为什么ECDSA验证失败


这是我的密码:

  • 生成签名(android):

  • 我有签名和公钥的输出是:

    (Signature string) MEYCIQC7Hz631IFGsUOogcRLeN99uM9hWgLr+LGzuJvR/6nBrgIhAMXgZcvXyMRCAELXlNNS1a9j iAT1x0q2C5Mdu+2aZKtN
    
    (公钥)

  • 使用PHP验证:

  • 评论:。。。但是verify函数不返回任何内容。所以我不确定

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


    注释:您如何看待添加base64.b64解码…因为在android代码中,我有一个
    linetxtMaHoa.setText(base64.encodeToString(signatureBytes,Ba‌​se64.DEFAULT));

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


    问题:例如--b“sha256”?“b”是二进制文件(内置函数,或者我必须将字符串sha256转换为二进制文件?)

    仅以字符串()的形式对我有效,例如:

    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')],)
    
    注意:抛出
    加密错误
    ,因为未使用创建
    签名的
    证书


    验证数据字符串的签名。
    证书是与生成签名的私钥相对应的X509实例。
    签名是提供签名本身的str实例。
    data是一个str实例,提供签名适用的数据。

    版本0.11中的新功能


    您的输出签名中有一个空白9j iANo,这是我的输入错误。可能会获得指向“/var/www/html/ca.pem”的链接,我想用
    pyopenssl
    ?验证它是否可以到达ca.pem文件,但我有一个问题:在Android中生成的字符串签名--->我将其编码到Base64并发送到服务器。但是,当我用PHP解码它时,它可能与登录Android不同。所以我可以在Android上验证此登录,但使用PHP,它失败了。pyopenssl?我没有使用过,可以吗指导我。Thank.PyOpenSSL它有错误:(certificate=pem.parse_file('ecc_publickey1.pem')[0]索引器:列表索引超出范围)如果我删除[0],它也有错误:(cert=crypto.load_证书(crypto.FILETYPE_pem,certificate.as_bytes())AttributeError:'list'对象没有属性'as_bytes')我在这里更新了签名和公钥:(sig=MEUCIEa5FlEm3mBp79ZG5f+rZdZ8o0eDWrAEE+TI8yZ+1501aiea0ddmvdduflkr9hpwe1rghxxae9a11gnnq/Iuut/Ts=),(origin string=这是origin string)和(公钥=----开始公钥----MFKWEWYHKOZJ0CAQYIKOZJ0DAQCDQGAEDDU15DEKY7EYVL9ELFMB/iNik1vq GYEC5SD9XB8MHWROUINZNICVU76BVCMDUSPR4PMRD3GRBPOLYG1USREQ=----结束公钥----。我使用ECDSA,为什么输出的是RSA?您的
    PEM
    无效!索引器表示文件中没有证书。请阅读有关确定的信息,让我再次检查。当我得到结果时,我将向您显示。感谢您的帮助:D
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEj07XEM+ulPyrdsfAf9prN2L2dNUd /Yy0rABcFdueAwYUf86f8Cc93Ws6sxzIvf2iKOapFby7EjHewjhLM/z7Qg==
     -----END PUBLIC KEY-----
    
    $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";
    }
    ?>
    
    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')],)