简体   繁体   English

从 Java 导出随机 RSA PublicKey 并使用 Web Crypto 将其导入 JavaScript

[英]Exporting a random RSA PublicKey from Java and importing it in JavaScript using Web Crypto

I am able to transfer a byte array from a Java server to a JavaScript server (is received as an Int32Array).我能够将字节数组从 Java 服务器传输到 JavaScript 服务器(作为 Int32Array 接收)。 With this, I want to be able to transfer a PublicKey generated in Java and receive it as a CryptoKey in JavaScript.有了这个,我希望能够传输在 Java 中生成的 PublicKey 并将其作为 CryptoKey 在 JavaScript 中接收。

The RSA Public key is generated in Java like so: RSA 公钥在 Java 中生成,如下所示:

SecureRandom sr = new SecureRandom();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048, sr);
KeyPair kp = generator.generateKeyPair();
PublicKey pKey = kp.getPublic();

What I have tried is to use Key#getEncoded() to get the public key as a byte array, transfer it to JavaScript using the aformenetioned method, and then import it like so:我尝试的是使用 Key#getEncoded() 将公钥作为字节数组获取,使用 aformenetioned 方法将其传输到 JavaScript ,然后像这样导入它:

const subtle = window.crypto.subtle;
await subtle.importKey("spki", array, { name: "RSA-OAEP", hash: "SHA-256" }, false, [ "encrypt" ])

Where "array" is the Int32Array received from the Java server.其中“array”是从 Java 服务器接收到的 Int32Array。 This does not work however, and I always get a non-descript DOMException stating "Data provided to an operation does not meet requirements".但是,这不起作用,并且我总是得到一个非描述性的 DOMException,说明“提供给操作的数据不符合要求”。 I have done the obvious troubleshooting, checking that the array is the same before and after sending, turning the TypedArray into an ArrayBuffer, encoding and decoding in base64 as a byte sanity check, and trying different algorithms but to no avail.我已经完成了明显的故障排除,检查发送前后数组是否相同,将 TypedArray 转换为 ArrayBuffer,在 base64 中编码和解码作为字节完整性检查,并尝试不同的算法但无济于事。

Some resources:一些资源:

Here is a sample key#getEncoded() byte array as reported by Java before sending (after sending is Int32Array([...]) with the same contents)这是发送前 Java 报告的示例 key#getEncoded() 字节数组(发送后是具有相同内容的 Int32Array([...]) )

[48, -126, 1, 32, 48, 11, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 10, 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -44, -97, 125, 40, -104, -77, -56, 30, 64, -51, -44, 35, -91, 83, 43, -92, 1, 104, -7, -71, 61, -111, 74, -17, -43, 96, 47, 5, 71, 57, -23, -80, 12, 23, -89, -5, 18, 56, 32, -125, -48, 115, -126, 45, 71, 73, -53, -68, -104, -95, 18, -76, 21, 22, 122, 26, -89, -128, -118, 99, -65, 89, -81, -120, 72, -85, 20, 44, -119, -38, 4, -1, -69, -105, -70, -52, 126, 58, 86, -9, 4, -55, 104, -81, 21, -91, -128, -101, -82, -15, -1, -4, -13, -116, 48, -91, -60, 81, 111, 53, 126, 91, -46, 16, -5, -99, 73, -40, -99, -24, -46, -75, -99, 48, -67, 92, -92, -78, -115, 76, -35, -51, 75, -56, 70, 56, -10, 13, -108, 56, 79, 34, -22, -123, -91, -12, 9, -21, -32, 22, -88, -79, -13, -35, 61, 24, -115, -93, 40, 46, -88, 5, -105, -69, 82, -57, 10, -15, -91, 21, 53, -60, -31, -102, -63, -35, 71, -72, 50, 2, 37, 93, -70, -87, -110, -69, -10, 88, 51, 118, 30, 45, -11, 74, -92, -109, -10, 102, 79, -128, 14, 61, 94, -100, 69, 97, 56, 38, -14, 29, -85, -78, 2, 31, -127, -107, 86, -16, -114, -7, -83, 31, 77, -120, 77, 73, 114, 38, -124, 31, 116, -83, 39, -36, 85, 92, 86, 52, 22, -90, -47, 101, 16, 94, -16, -95, -33, 68, 112, 88, 94, -47, 121, -83, 3, -80, 111, 21, -42, 65, -101, 72, -126, 4, -83, -11, 2, 3, 1, 0, 1]

The same data expressed in hexadecimal以十六进制表示的相同数据

30 82 01 20 30 0B 06 09 2A 86 48 86 F7 0D 01 01 0A 03 82 01 0F 00 30 82 01 0A 02 82 01 01 00 D4 9F 7D 28 98 B3 C8 1E 40 CD D4 23 A5 53 2B A4 01 68 F9 B9 3D 91 4A EF D5 60 2F 05 47 39 E9 B0 0C 17 A7 FB 12 38 20 83 D0 73 82 2D 47 49 CB BC 98 A1 12 B4 15 16 7A 1A A7 80 8A 63 BF 59 AF 88 48 AB 14 2C 89 DA 04 FF BB 97 BA CC 7E 3A 56 F7 04 C9 68 AF 15 A5 80 9B AE F1 FF FC F3 8C 30 A5 C4 51 6F 35 7E 5B D2 10 FB 9D 49 D8 9D E8 D2 B5 9D 30 BD 5C A4 B2 8D 4C DD CD 4B C8 46 38 F6 0D 94 38 4F 22 EA 85 A5 F4 09 EB E0 16 A8 B1 F3 DD 3D 18 8D A3 28 2E A8 05 97 BB 52 C7 0A F1 A5 15 35 C4 E1 9A C1 DD 47 B8 32 02 25 5D BA A9 92 BB F6 58 33 76 1E 2D F5 4A A4 93 F6 66 4F 80 0E 3D 5E 9C 45 61 38 26 F2 1D AB B2 02 1F 81 95 56 F0 8E F9 AD 1F 4D 88 4D 49 72 26 84 1F 74 AD 27 DC 55 5C 56 34 16 A6 D1 65 10 5E F0 A1 DF 44 70 58 5E D1 79 AD 03 B0 6F 15 D6 41 9B 48 82 04 AD F5 02 03 01 00 01

Thank you to anybody who takes time to help or reply!感谢任何花时间帮助或回复的人!

First of all a working solution: The DER encoded X.509/SPKI key generated with Key#getEncoded() is Base64 encoded and then imported to the JavaScript side as follows:首先是一个可行的解决方案:使用Key#getEncoded()生成的 DER 编码的 X.509/SPKI 密钥经过 Base64 编码,然后导入到 JavaScript 端,如下所示:

 (async () => { const subtle = window.crypto.subtle; var keyAB = b642ab("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuKRgspvg47d4I3pAzCIWKSim2Rs1QeTVE1Hs+P099PkiuMt5dq5GIaIT1DZTYwJrwtUpxnMcr1TNdWGGfovDLJuIRXUFeST1xOD9+rA4FhVZPO/x6ts2TYKiueEq/qPlXREXw8aVq+msw0nYhHFIAAyrtmj7UR6gD3xxl1ghviIycKqUf7rL98b1d6YkYoNW62aIP/u3cJ5v3Fhnth02Cb02M/fX5gvFKJ3Nj2ARbLygZWbO3U09Vs/hnElxE2k1sKxYRqImJdQM04oQOXVVpafZP7eF9/T+YYDxMLcEKAwH9z0fTt9HaL4gyiDWUT02r6qWF7vI85I1jrPLn71mQIDAQAB") var key = await subtle.importKey("spki", new Uint8Array(keyAB), { name: "RSA-OAEP", hash: "SHA-256" }, false, [ "encrypt" ]) console.log(key) })(); function b642ab(base64string){ return Uint8Array.from(atob(base64string), c => c.charCodeAt(0)).buffer; }

The problem is caused by the Int32Array type you used.问题是由您使用的Int32Array类型引起的。 A typed array is an array-like view of an underlying ArrayBuffer .类型化数组是底层ArrayBuffer的类数组视图。 In an Int32Array each element corresponds to 4 bytes.Int32Array ,每个元素对应 4 个字节。
Since your Int32Array contains the same values as your Key#getEncoded() , the underlying ArrayBuffer contains 4 times as many values and therefore no longer corresponds to the original key.由于您的Int32Array包含与Key#getEncoded()相同的值,因此基础ArrayBuffer包含的值是原来的 4 倍,因此不再对应于原始键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM