gpt4 book ai didi

javascript - Java 签名/验证 key 和 Javascript WebCrypto 验证失败

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:36:50 24 4
gpt4 key购买 nike

我正在努力

  1. 生成签名/验证 key (RSA)
  2. 在 Java 网络应用程序(让调用服务器端)上签署一个值(使用这些 key )
  3. 为了让 Web 客户端验证 - 公钥导入为 RSASSA-PKCS1-v1_5 + SHA-256,(在浏览器中,使用 WebCrypto API/客户端)

我在验证签名值(在 Java 服务器端签名)时遇到问题,即使公共(public)签名/验证 key 已作为 JWK 在客户端成功导入。

我想知道在我可能遇到的任何步骤(OpenSSL、Java 或 Javascript)中是否存在任何算法兼容性问题。

用于生成 key 的 OpenSSL 命令

openssl genrsa -out privatekey.pem 2048
openssl rsa -in privatekey.pem -pubout > publickey.pub
openssl pkcs8 -topk8 -inform PEM -outform DER -in privatekey.pem -out privatekey-pkcs8.pem

使用 Java 导入 key (服务器端)

public static KeyPair generateSignKeyPair() throws ... {
byte[] privBytes = b64ToByteArray(PRIVATE_KEY_PEM_VALUE);
byte[] pubBytes = b64ToByteArray(PUBLIC_KEY_PEM_VALUE);

// private key
KeySpec keySpec = new PKCS8EncodedKeySpec(privBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

// public key (javaPubSignKey)
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(pubBytes);
PublicKey publicKey = keyFactory.generatePublic(X509publicKey);

return new KeyPair(publicKey, privateKey);
}

用 Java 签署一个值(服务器端)

 public static byte[] generateSignature(PrivateKey signPrivateKey, byte[] data) throws ... {
Signature dsa = Signature.getInstance("SHA256withRSA");
dsa.initSign(signPrivateKey);
dsa.update(data);
return dsa.sign();
}

将它们发送到 WebCrypto API 的 Web 应用程序以作为客户端/浏览器进行验证(客户端知道第一步中生成的公钥)。

// Import public sign/verify key (javaPubSignVerifyKey)
var signatureAlgorithm = {
name: 'RSASSA-PKCS1-v1_5',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {
name: 'SHA-256'
}
};
// JWK format (1)
crypto.subtle.importKey(
'jwk', javaPubSignVerifyKey, signatureAlgorithm, false, ['verify']
).then(success, error);

function success(key) {
signatureVerifyPublicKey = key;
}

注意 (1):在 Java 端,我使用 com.nimbusds.jose.jwk.JWK 将 publicKey 导出为 JWK 格式。

WebCrypto 成功导入签名 key 。但是当涉及到验证时,它失败了(验证 boolean 值是false)。

crypto.subtle.verify(
signatureAlgorithm,
signatureVerifyPublicKey,
signature, // bytes in Int8Array format (2)
data // bytes in Int8Array format
).then(
function (valid) {
// valid === false
}
)

注意 (2):另请注意,我在 WebCrypto 上找到的每个示例都使用 Uint8Array 来表示字节数组,但由于 Java 生成了 signed 字节数组,因此我需要使用Int8Array 这样签名值就不会被污染(也许这也是一个问题)。

编辑: 作为引用,它原来是另一个不相关的问题 - 我在 Javascript 中两次从 base64 转换预期数据而没有注意到它;自然验证失败。

最佳答案

请根据您的代码检查这个简单的代码,以导入 RSA 公钥 (spki) 并验证签名。我使用类似的 Java 代码生成了 key 和签名

var publicKeyB64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVdZDEs6htb3oxWstz7q+e5IwIRcptMNJiyemuoNyyjtiOy+0tEodjgo7RVoyUcGU3MysEivqvKdswQZ4KfwQCBLAR8DRzp3biAge5utZcKsQoQaC1rCEplfmzEo5ovIlBcMq5x1BxnrnlwEPRmM7MefRa+OeAOQJcstHcrJFO7QIDAQAB";
var dataB64 = "aGVsbG8=";
var signatureB64 = "aEOmUA7YC5gvF6QgH+TMg0erY5pzr83nykZGFtyGOOe+6ld+MC4/Qdb608XiNud+pBpzh0wqd6aajOtJim5XEfCH8vUPsv45aSPtukUIQTX00Oc1frIFDQI6jGJ4Q8dQYIwpqsyE2rkGwTDzt1fTTGiw54pLsJXjtL/D5hUEKL8=";
var signatureAlgorithm = {name: 'RSASSA-PKCS1-v1_5',modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]),hash: { name: 'SHA-256' }};

//convert public key, data and signature to ArrayBuffer.
var publicKey = str2ab(atob(publicKeyB64));
var data = str2ab(atob(dataB64));
var signature = str2ab(atob(signatureB64));

crypto.subtle.importKey("spki", publicKey, signatureAlgorithm, false,["verify"]).
then(function(key){
console.log(key);
return crypto.subtle.verify( signatureAlgorithm, key, signature, data);
}).then( function (valid) {
console.log("Signature valid: "+valid);
}).catch(function(err) {
alert("Verification failed " + err );
});

我无法准确重现该问题。使用您链接的 str2ab 实用程序函数,代码可以完美运行。

//Utility function
function str2ab(str) {
var arrBuff = new ArrayBuffer(str.length);
var bytes = new Uint8Array(arrBuff);
for (var iii = 0; iii < str.length; iii++) {
bytes[iii] = str.charCodeAt(iii);
}
return bytes;
}

我建议比较两个代码以找出差异

关于javascript - Java 签名/验证 key 和 Javascript WebCrypto 验证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40863304/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com