1+ /**
2+ * 与后端 `cryptography` RSA-OAEP-SHA256(MGF1-SHA256、label 空)对齐的加密。
3+ * - 安全上下文下优先用 Web Crypto(性能更好)
4+ * - 纯 HTTP + 非 localhost 时无 crypto.subtle,使用 node-forge 纯 JS 实现,仍为非明文传输
5+ */
6+ import forge from 'node-forge' ;
7+
18function pemToArrayBuffer ( pem : string ) : ArrayBuffer {
29 const b64 = pem
310 . replaceAll ( / - - - - - ( B E G I N | E N D ) P U B L I C K E Y - - - - - / g, '' )
@@ -19,7 +26,19 @@ function arrayBufferToBase64(buf: ArrayBuffer): string {
1926 return btoa ( binary ) ;
2027}
2128
22- export async function rsaOaepEncryptBase64 (
29+ function rsaOaepEncryptForgeBase64 ( publicKeyPem : string , plaintext : string ) : string {
30+ const publicKey = forge . pki . publicKeyFromPem ( publicKeyPem ) ;
31+ const encoded = forge . util . encodeUtf8 ( plaintext ) ;
32+ const encrypted = publicKey . encrypt ( encoded , 'RSA-OAEP' , {
33+ md : forge . md . sha256 . create ( ) ,
34+ mgf1 : {
35+ md : forge . md . sha256 . create ( ) ,
36+ } ,
37+ } ) ;
38+ return forge . util . encode64 ( encrypted ) ;
39+ }
40+
41+ async function rsaOaepEncryptSubtleBase64 (
2342 publicKeyPem : string ,
2443 plaintext : string ,
2544) : Promise < string > {
@@ -39,3 +58,13 @@ export async function rsaOaepEncryptBase64(
3958 ) ;
4059 return arrayBufferToBase64 ( encrypted ) ;
4160}
61+
62+ export async function rsaOaepEncryptBase64 (
63+ publicKeyPem : string ,
64+ plaintext : string ,
65+ ) : Promise < string > {
66+ if ( typeof globalThis . crypto ?. subtle !== 'undefined' ) {
67+ return rsaOaepEncryptSubtleBase64 ( publicKeyPem , plaintext ) ;
68+ }
69+ return rsaOaepEncryptForgeBase64 ( publicKeyPem , plaintext ) ;
70+ }
0 commit comments