【问题标题】:M2Crypto and java.security return different signed messagesM2Crypto 和 java.security 返回不同的签名消息
【发布时间】:2019-02-23 02:20:04
【问题描述】:

我在将某个项目的一些 Java 代码移植到 Python 时遇到了困难。

以下 Java 代码用于对发布到服务器进行验证的伪随机 nonce 进行签名:

private static final String NONCE_SIGNATURE_ALGORITHM = "SHA512withRSA";

@JsonProperty
private String encodedData;

@JsonProperty
private String encodedSignedData;

@SuppressWarnings("unused")
private cacertnonceverification() {
}

public cacertnonceverification(byte[] decodedData, PrivateKey privateKey)
        throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    byte[] decodedSignedData = sign(privateKey, decodedData);
    encodedData = Base64.getEncoder().encodeToString(decodedData);
    encodedSignedData = Base64.getEncoder().encodeToString(decodedSignedData);
}

@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("CACertNonceVerificationData{");
    sb.append("encodedData='").append(encodedData).append('\'');
    sb.append(", encodedSignedData='").append(encodedSignedData).append('\'');
    sb.append('}');
    return sb.toString();
}

private byte[] sign(PrivateKey privateKey, byte[] dataBytes)
        throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    Signature sig = Signature.getInstance(NONCE_SIGNATURE_ALGORITHM);

    sig.initSign(privateKey);
    sig.update(dataBytes);

    return sig.sign();
}

这按预期工作,但以下 Python 代码为由相同私钥签名的相同 nonce 返回不同的值。我已经使用 PyCrypto 和 M2Crypto 进行了测试——在签署 nonce 时它们都返回相同的值,但它们与 Java 返回值不同。

def sign_nonce(nonce, privKey):

   key=EVP.load_key(privKey)
   key.reset_context(md='sha512')
   key.sign_init()
   key.sign_update(nonce.encode('utf-8'))

   return binascii.b2a_hex(key.sign_final()).decode("utf-8")

def sign_string(message, privKey):

   f = open(privKey, 'r')
   keyString = f.read()
   keyString = keyString.encode('utf-8')
   key = rsa.PrivateKey.load_pkcs1(keyString)

   return binascii.b2a_hex(rsa.sign(message.encode(), key, 'SHA-512')).decode('utf-8')

知道是什么导致了这种差异,我缺少什么吗?

谢谢!


编辑: 我的 Python 脚本确实验证了签名的 nonce 是有效的,并且我对 Python 和 Java 代码使用了相同的公钥和私钥,但显然得到了不同的签名值结果。这对我来说意味着 java.security 和 M2Crypto/RSA 使用的签名算法是不同的,但我可能有点离谱——我是加密新手。


编辑 2: 我尝试使用 M2Crypto.RSA 对 nonce 进行签名,但得到的响应仍然不同,但修改了代码,现在 M2Crypto EVP 和 RSA,并且 rsa 输出相同的签名值。仍然没有运气让它们与 Java 的预期值相匹配:

预期值:6d90537599b912ac0de9f68dc0d104a04c5aa74e35262f73872bb01ed1e2cc37100ff1a00735da307fa325f3e30f3c81157755fc60c7ee69bd91bf44b6a5f5e4161bdd67cf982550d992a0a16d12ed5ea30b878a8b2f8eee61cf64e083d7b74a635dabba44bf0b51b9b305aa901b3d090712ee3994057b076d53366a3a387de0f7b2e220cf11239facfce0df6d9a54dfb365f7d3996ea20b55ec75e3661cf95392eda75696cfc6bebda304a2671428dad38a43d5a579550595fe9180539b2b7eb3d568a1f8ce05ded2ae3241a732fffd1404f989eea3e68dda6cd13bfcd6b2e47e64685763a6c3c0f1c47f84c908e22e718254b9f46a7a1de7e2280ccb59c1c5 P>

M2Crypto RSA:2c973dd7006c058293787504203e36e921ae286f44bcdbf2bd4b48c8a7d9a73723c058d1bcd15b76f6a7145d55cf6109f4bbe5f3953d953177117ef4733e4d3ac22e8a4d320ae6c3a626ddce2a3d5db6b0f10656dd49179c3d60ba912bf21b2e2eac5def74aa6809b74d7711cbb86d719b1fe4df5b7215067af34de3e03859e2c919587bc7f00ec96c6b678c5fc8e114cebae3f5d301811dacc247cd2df9dadf62bccd524147f582f77f0ce29077c7352c8b9893056dce3d65de44d0fc45b88363db9df59c142a01d8f32bf48f05183757e3cd0954c528a7601f4edb56ed9175b219e08aa79514694aedff45bbb365e7d54e534973f6a2aa9f22da12890bbbb5 P>

M2Crypto EVP:2c973dd7006c058293787504203e36e921ae286f44bcdbf2bd4b48c8a7d9a73723c058d1bcd15b76f6a7145d55cf6109f4bbe5f3953d953177117ef4733e4d3ac22e8a4d320ae6c3a626ddce2a3d5db6b0f10656dd49179c3d60ba912bf21b2e2eac5def74aa6809b74d7711cbb86d719b1fe4df5b7215067af34de3e03859e2c919587bc7f00ec96c6b678c5fc8e114cebae3f5d301811dacc247cd2df9dadf62bccd524147f582f77f0ce29077c7352c8b9893056dce3d65de44d0fc45b88363db9df59c142a01d8f32bf48f05183757e3cd0954c528a7601f4edb56ed9175b219e08aa79514694aedff45bbb365e7d54e534973f6a2aa9f22da12890bbbb5 P>

RSA:2c973dd7006c058293787504203e36e921ae286f44bcdbf2bd4b48c8a7d9a73723c058d1bcd15b76f6a7145d55cf6109f4bbe5f3953d953177117ef4733e4d3ac22e8a4d320ae6c3a626ddce2a3d5db6b0f10656dd49179c3d60ba912bf21b2e2eac5def74aa6809b74d7711cbb86d719b1fe4df5b7215067af34de3e03859e2c919587bc7f00ec96c6b678c5fc8e114cebae3f5d301811dacc247cd2df9dadf62bccd524147f582f77f0ce29077c7352c8b9893056dce3d65de44d0fc45b88363db9df59c142a01d8f32bf48f05183757e3cd0954c528a7601f4edb56ed9175b219e08aa79514694aedff45bbb365e7d54e534973f6a2aa9f22da12890bbbb5 P>

【问题讨论】:

  • 您在 Windows 上吗?您是否尝试在 Java 上也指定 UTF-8?我已经多次遇到这个(有点棘手的)问题 O:)
  • 我在 Mac 上运行,Java 代码是我需要满足的标准。我将尝试在 Python 中删除 UTF-8 编码,看看它是否会影响输出。

标签: java python rsa m2crypto java-security


【解决方案1】:

我能够通过同时使用 EVP 和 RSA 模块来签署我的 nonce 来解决这个问题:

key = RSA.load_key(privKey)
md = EVP.MessageDigest('sha512')
md.update(message)
digest=md.final()
signature = key.sign(digest, "sha512")

return b64encode(signature).decode('utf-8') 

【讨论】:

    猜你喜欢
    • 2012-02-03
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多