我想Java的標誌/驗證密鑰和Javascript WebCrypto驗證失敗
- 生成登錄/在Java Web應用程序驗證密鑰(RSA)
- 符號的值(使用這些密鑰)(讓調用服務器端)爲了
- 到Web客戶端驗證 - 公共密鑰導入爲
RSASSA-PKCS1-v1_5
+SHA-256
,(在瀏覽器中,使用WebCrypto API /客戶端)
我^ h即使在客戶端將公共簽名/驗證密鑰成功導入爲JWK,仍會出現驗證簽名值(在Java服務器端簽名)的問題。
我想知道在我可能遇到的任何步驟(OpenSSL,Java或Javascript)中是否有任何算法兼容性問題問題。
用來生成密鑰
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(服務器端)
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(服務器端)的值。OpenSSL的命令
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應用程序,以便作爲客戶端/瀏覽器進行驗證(客戶端知道publicKe y在第一步中生成)。
// 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
導出的公鑰來JWK格式。
簽名密鑰由WebCrypto成功導入。但是當涉及到驗證時,它會失敗(驗證布爾值爲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的產生簽署字節數組,我需要使用Int8Array
使簽名值不污染(也許這也是一個問題)。原來是另一個無關的問題 - 我在Javascript中轉換了base64的預期數據,但沒有注意到它;自然驗證失敗。
的Java字節'[]'門店值。我認爲你需要使用'Uint8Array'和'ArrayBuffer'。你可以嘗試使用這裏記錄的'stringToArrayBuffer'函數http://stackoverflow.com/questions/36018233/how-to-load-a-pkcs12-digital-certificate-with-javascript-webcrypto-api/37407739#37407739代表「數據」和「簽名」? – pedrofb
謝謝,依然無法正常工作。也許我需要改變實現的基本原理:考慮在Java中導入X509證書並使用'pki.js' +'asn1.js'在JavaScript中爲WebCrypto提取publicKey(證書)以驗證([example這裏](https://github.com/PeculiarVentures/PKI.js/blob/master/examples/certificate-decode-example.html)) – nuno
我想這不是公鑰的問題,因爲它提出了一個當您導入JWK時例外。但是,要確保它可以以'spki'格式導入(將二進制RSA密鑰轉換爲ArrayBuffer) – pedrofb