Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用window.crypto.api从浏览器解密RSA消息_Javascript_Rsa_Encryption Asymmetric_Window.crypto - Fatal编程技术网

Javascript 使用window.crypto.api从浏览器解密RSA消息

Javascript 使用window.crypto.api从浏览器解密RSA消息,javascript,rsa,encryption-asymmetric,window.crypto,Javascript,Rsa,Encryption Asymmetric,Window.crypto,我正在尝试使用相应的私钥对使用公钥编码的RSA 2048位消息进行解码。环境是google chrome,我使用的是window.crypto.minuteAPI 我使用openssl工具生成密钥对并对消息进行编码: # generate keys and put the private one in file private_key.pem openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:

我正在尝试使用相应的私钥对使用公钥编码的RSA 2048位消息进行解码。环境是google chrome,我使用的是
window.crypto.minute
API

我使用
openssl
工具生成密钥对并对消息进行编码:

# generate keys and put the private one in file private_key.pem
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

# extract public key in file public_key.pem
openssl rsa -pubout -in private_key.pem -out public_key.pem

# encode message input.txt using the public key
openssl rsautl -encrypt -oaep -inkey public_key.pem -pubin -in input.txt -out msg_rsa.enc

# convert the encoded msg in base 64 format
base64 msg_rsa.enc > msg_rsa_64.enc
这是我用来解码消息的javascript代码:

function str2ab(str) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

async function importPrivateKey(pem) {
    pem = pem.replace( /[\r\n]+/gm, "" );
    // fetch the part of the PEM string between header and footer
    const pemHeader = "-----BEGIN PRIVATE KEY-----";
    const pemFooter = "-----END PRIVATE KEY-----";
    const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
    // base64 decode the string to get the binary data
    const binaryDerString = window.atob(pemContents);
    // convert from a binary string to an ArrayBuffer
    const binaryDer = str2ab(binaryDerString);

    return window.crypto.subtle.importKey(
      "pkcs8",
      binaryDer,
      {
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: "SHA-256",
      },
      true,
      ["decrypt"]
    );
}

async function decryptRSA(_key, ciphertext) {
    let decrypted = await window.crypto.subtle.decrypt(
      {
        name: "RSA-OAEP"
      },
      _key,
      ciphertext
    );
    const dec = new TextDecoder();
    return dec.decode(decrypted);
}

const fromBase64 = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0));

window.onload = init;

async function init() {

    const privateKey = '-----BEGIN PRIVATE KEY-----\
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3jmTi3O1k2YXs\
AM6nNTTIzDq5YWkxYrYb6cpO9eYuzmphgRnVDR6a1YWRXMoCuCfuNXcDGywzudRn\
bBMw0FHKLUqCttVHGpZYu0+0tRR10ubxiz/xnd/aCmRYHcmUNn8Qdh3KU59A9HK5\
HhYFf1vhK8r3fkoO4CjoGo1ROzXyMybUSy+4mSNscUtt5LwrVn48vXvG5i5B4DRT\
nM4cINmutEzA2s5cDt+dzU4Py71fKBRDRIGGn0vdVSoZKbWuhm5WewyRewCk7HFc\
PALCi5/1A7VKDAHUC4FlXmuG2+wzdchEyxMj6oLR7+BkKFQaTmuMM/22cGBjVTVt\
pSr3iDovAgMBAAECggEBAIuTQW+oovNu3IDq1DkdIjgV5AmW4tBkySlMi0OjhBbP\
auEdtDDnOwBtoJU6Q3nx4psmGItKHEBw6+yAp88UeT0NV30x3delhfGO7Trx/s7h\
Qi8lvcfSTqeUA11luSR0lAZGaryw/YX820eccw5XG9yK2ll7tIC/PxvPJOpB5fF2\
XGxGrionTjHDzXJ1OWX0i0aZlNNufInJAHhlt7aT3GiQMKcQs+AUb/+bWxI3Hln8\
KcL13EUlD4pJW8vtTK3gCnQNKKMoPB5Ugqe5BrU8ElkBz+zSKDnVwt5bgjrlucYz\
rKJxWr6/qTRZkzmvkhaJeNzzepfwkFsQ/eHcxYrtuDECgYEA8OXkQ2SqYDZwizCd\
SuVkx2zHm3zXYRSlRtnXYoUdJyTyuZ4k2GvXBrlwRsOJ14emVkHKyR5enmNjwrW5\
dcD2tbBzavcqOYAMiHcKklcS/gWgPx0X5QFHU33vr8u51BQWCz75lxddWNKxVAN/\
cUTugONtS4+EP4dSZhuxHt6RscsCgYEAwxA9QmZrI54hjMkIyqwmviRmIk42S5kk\
OxbhxBbt5qVueLRB092JyGmCR2kYiqdHCYkGFDOE4kni6Bsszq5CSJvhiATFeZeX\
ldFQeZqAiRY2rAd7xD1upMug/cK3ODA8k3k/e72CtyxtBTR01q29SnPx5p/57MrI\
3ogddHlGvK0CgYEA3VqhELwjQh1D9OJK5lM683SlRd7FGdOauyvYmhKu4xU0ZBNI\
0ATnpKoo3R04P+/JjGEQMRXS4794H6ZUMDuLdxAYPiW3ivZ6jbq04BtavEf3I4dc\
OXWfULzbzbFpo9KBHvxS4974S3Hut8AvDqnEbnKML25EmwuBT4oKis8BGVkCgYEA\
nusPDZbFeNou+TUbzYrdcZHUB+TyhTq58s4clxYbMgrbaslozAQ0aavT8Pvle6j2\
zgTth+3FOFr72x+wrJ358I/W+Wrxu7NOU0eZqci/KXCIkDT0l5d5GhewDK3jeYqK\
/5cLqnNmGHfARjpLak9X5V162erBwjIf3nTEkozvnW0CgYB6L1CX3DkTFH3OBcJe\
SvV18RDUfNI8MpUKcpofmwwvgER3GrehSZHRVxVwNbnJOqbh/oiwmmNJieKrFsk9\
EzCRBVWdZByHHYW2js+gCrAp+ghnl1QEAeCU7YTxCJ2fZIAmfB9X4u/7ARtVxnZY\
mOWlm65KUYr5lf2Ws5plL4pCRA==\
-----END PRIVATE KEY-----';

    const ciphertext = 'F6/NwENdUZSl+vrgpWVkyWPQuYaTGDNZPIvj4KmIRHVx4qybxN24LPIgk0Rl84KHcLFadZWCjNpM\
vg3l826OaKZAtwvIp9IxVrMbvtNOymY6A1koKvC9ema92SR4DC9hmTtMxhUB6r3XgACtRLFqMfg+\
zYSHfFqQEGJg3yZ43hfzIq/gCfHPk5sZXASq5WY5b9yd4gRonn5D4OCD6xna/r5ovHfrpO/Fwe8N\
eeY2gqTAdtzvtmOw/HLQhGANejpJYr1IriQbepM7jLjBkJX+uCn38O1MxpQb7s5RXTvGvoEoofWV\
Cq8gNFhgnVFuurdZUiY0bn58UwaVFdwzEfDSUQ==';

    try {
        const key = await importPrivateKey(privateKey);
        const decoded = await decryptRSA(key, fromBase64(ciphertext));
        console.log(decoded);
    } catch(error) {
        console.log(error);
    }
}
函数str2ab(str){
const buf=新阵列缓冲区(str.length);
const bufView=新的UINT8阵列(buf);
for(设i=0,strLen=str.length;iUint8Array.from(atob(base64String),c=>c.charCodeAt(0));
window.onload=init;
异步函数init(){
const privateKey='----开始私钥-----\
MIIEVWIBADANBGKQHKIG9W0BAQEFAAASCBKWGGGGSLAGEAAOIBAQC3JMTI3O1K2YXS\
AM6nNTTIzDq5YWkxYrYb6cpO9eYuzmphgRnVDR6a1YWRXMoCuCfuNXcDGywzudRn\
bBMw0FHKLUqCttVHGpZYu0+0tRR10ubxiz/xnd/ACMRYHCMUN8QDH3KU59A9HK5\
HhYFf1vhK8r3fkoO4CjoGo1ROzXyMybUSy+4MSNCUT5LWRVN48VxVG5I5B4DRT\
nM4cINmutEzA2s5cDt+DZU4PY71FKBDRIGGN0VDVSOZKBWUHM5WEWYREWCK7HFC\
PALCi5/1A7VKDAHUC4FlXmuG2+wzdchEyxMj6oLR7+BKKKFQATMUMM/22CGBJVT\
pSr3iDovAgMBAAECggEBAIuTQW+oovnu3idq1dkddijgv5amw4tbkyslmi0ojhbp\
AUEDTDNOWBtoJ6Q3NX4PSMGITKHEBW6+yAp88UeT0NV30x3delhfGO7Trx/s7h\
Qi8lvcfSTqeUA11luSR0lAZGaryw/YX820eccw5XG9yK2ll7tIC/PxvPJOpB5fF2\
xgxgriontjhdzj1owx0i0azlnnufinjahhlt7at3giqmkcqs+AUb/+bWxI3Hln8\
KcL13EUlD4pJW8vtTK3gCnQNKKMoPB5Ugqe5BrU8ElkBz+zSKDnVwt5bgjrlucYz\
rKJxWr6/qTRZkzmvkhaJeNzzepfwkFsQ/eHcxYrtuDECgYEA8OXkQ2SqYDZwizCd\
SUVKX2ZHM3ZXYRSLRTNXYOUDJYTYYUZ4K2GVBRLWRSOJ14EMVKKKYR5ENJWRW5\
DCD2TBBZAVCQOYAMICHCKKLCS/GWGPX0x5QFHU33VR8U51BQWCZ75LXDWNKXVAN/\
cUTugONtS4+EP4dSZhuxHt6RscsCgYEAwxA9QmZrI54hjMkIyqwmviRmIk42S5kk\
OXBHXBBT5QVuelRB092JYGMCR2KYIQDHCYKGFDOE4KNI6BSZQ5CSJVHIATZEX\
ldFQeZqAiRY2rAd7xD1upMug/cK3ODA8k3k/E72CTYXTBR01Q29SNPX5P/57MrI\
3ogddHlGvK0CgYEA3VqhELwjQh1D9OJK5lM683SlRd7FGdOauyvYmhKu4xU0ZBNI\
0ATnpKoo3R04P+/JjGEQMRXS4794H6ZUMDuLdxAYPiW3ivZ6jbq04BtavEf3I4dc\
OxWFulzBzBFPO9KBHVXS4974S3HUT8AVDQNEBNKML25EMWUBT4OKIS8BGVKGYEA\
nusPDZbFeNou+TUbzYrdcZHUB+TyhTq58s4clxYbMgrbaslozAQ0aavT8Pvle6j2\
zgTth+3FOFr72x+wrJ358I/W+Wrxu7NOU0eZqci/KXCIkDT0l5d5GhewDK3jeYqK\
/5clqnnmghfarjplak9x5v162erbwjif3ntekozvnw0cgyb6lcx3dktfh3obcje\
SVV18RDUFNI8MPUKCPOFMWWVGER3GREHSZHRVxVWNBNJOKBH/oiwmmNJieKrFsk9\
EZCRBVWDZBYHYW2JS+gCrAp+ghnl1QEAeCU7YTxCJ2fZIAmfB9X4u/7ARtVxnZY\
MOWLM65KUYR5LF2WS5PL4PCRA==\
-----结束私钥------';
常量密文='F6/NwENdUZSl+VRGPWVKYWPQUYATGDNZPIVJ4KMIRRHVX4QYBXN24LPIGK0RL84KHCLFADZWCJNPM\
VG3L826OAKZATWVIP9IXVRMBVTNOY6A1KOKVC9EMA92SR4DC9HMTTMXHUB6R3XGACTRLLFQMFG+\
ZYSHFFFQEGJG3YZ43HFZIQ/gCfHPk5sZXASq5WY5b9yd4gRonn5D4OCD6xna/r5ovHfrpO/Fwe8N\
eeY2gqTAdtzvtmOw/HLQHGANEJPJYR1IIQBEPM7JLJBKJX+UCN38O1MXPQB7S5RXTVGVOEWV\
Cq8gNFhgnVFuurdZUiY0bn58UwaVFdwzEfDSUQ==';
试一试{
const key=等待importPrivateKey(privateKey);
const decoded=等待解密RSA(密钥,来自base64(密文));
控制台日志(已解码);
}捕获(错误){
console.log(错误);
}
}
运行代码时,我在
window.crypto.minute.decrypt
中遇到了一个异常,出现了一条毫无用处的消息“DOMException”

我做错了什么


谢谢

只有一个缺陷:发布的代码当前使用带有SHA256的OAEP。如果将带有SHA1的OAEP用作填充,则可以使用发布的密钥解密密文

此外,函数
fromBase64
可用于Base64将密钥解码为
类型Darray
,因此实际上不需要函数
str2ab
(当然,这不是错误,只是冗余)

const fromBase64=base64String=>Uint8Array.from(atob(base64String),c=>c.charCodeAt(0));
const getPkcs8Der=pkcs8Pem=>{
pkcs8Pem=pkcs8Pem.replace(/[\r\n]+/gm,”);
const pkcs8PemHeader=“----开始私钥------”;
const pkcs8pemfoter=“----结束私钥------”;
pkcs8Pem=pkcs8Pem.substring(pkcs8PemHeader.length,pkcs8Pem.length-pkcs8PemFooter.length);
从Base64返回(pkcs8Pem);
}		
异步函数importPrivateKey(pkcs8Pem){
返回等待窗口.crypto.division.importKey(
“pkcs8”,
获取PKCS8DER(pkcs8Pem),
{
名称:“RSA-OAEP”,
散列:“SHA-1”,//用SHA-1替换SHA-256
},
是的,
[“解密”]
);
}
异步函数解密RSA(密钥、密文){
let decrypted=等待window.crypto.minute.decrypt(
{
名称:“RSA-OAEP”
},
钥匙
密文
);
const dec=新文本解码器();
返回dec.decode(解密);
}
window.onload=init;
异步函数init(){
const privateKey=
'----开始私钥-----\
MIIEVWIBADANBGKQHKIG9W0BAQEFAASBKWGG