【发布时间】:2021-09-15 03:53:19
【问题描述】:
我正在尝试使用 RSA 公钥从服务器获取加密响应。密码在服务器端生成,但在客户端解码失败。 Web 加密 API 抛出 DOM 异常。
Java 服务器:
byte[] exponentBytes = Base64.getUrlDecoder().decode(body.exponent);
byte[] modulusBytes = Base64.getUrlDecoder().decode(body.modulus);
BigInteger exponent = new BigInteger(1, exponentBytes);
BigInteger modulus = new BigInteger(1, modulusBytes);
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherBytes = cipher.doFinal("hello".getBytes())
return Base64.getEncoder().encodeToString(cipherBytes);
浏览器:
const key = await window.crypto.subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 512,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256',
},
true,
['encrypt', 'decrypt'],
)
const jwk = await window.subtle.exportKey('jwk', key.publicKey);
const response = await fetch('/foo/bar', { method: 'post', body: { exponent: jwk.e, modulus: jwk.n } });
const body = await response.text();
const binary = window.atob(body);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
await window.crypto.subtle.decrypt(
{ name: 'RSA-OAEP' },
key.privateKey,
bytes.buffer,
); // returns undefined throws the error
编辑:经过进一步研究,我发现:
- (显然)web crypto api 生成的密码在解码时没有问题。
- 从服务器端返回字节数组本身没有帮助。
【问题讨论】:
-
确切的错误是什么
-
它只是抛出 DOMException
-
看起来 crypto.subtle 不喜欢小于 2048 的“模数长度”
-
使用
hash: 'SHA-1'你可以有最低modulusLength: 1024- 使用hash: 'SHA-256'似乎最低是modulusLength: 2048- 除了在谷歌可怕的文档中之外,看不到modulusLength: 512正在使用 -
我建议在这里调试/解密返回的加密内容gchq.github.io/CyberChef/… 只是为了验证您使用的密钥对是否正确
标签: javascript java cryptography rsa webcrypto-api