gpt4 book ai didi

javascript - RSA 加密、PHP 加密 (phpseclib) 和 JavaScript 解密 (crypto.subtle)

转载 作者:行者123 更新时间:2023-12-04 07:43:07 33 4
gpt4 key购买 nike

我想要做的是在 javascript 中生成一个 key 对,并在 PHP 中使用这些加密,然后用 JS 解密。
我在附加的代码中有两个问题

  • 它不会从装甲文本块重新加载私钥
  • 并且它不会解密 PHP 加密的内容

  • 两者都抛出错误 DOMException,而不是一个有用的错误。
    所以这是我的代码...
    PHP/Java 脚本
    <?php
    use phpseclib3\Crypt\PublicKeyLoader;
    use phpseclib3\Crypt\RSA;
    if ($_POST) {
    $public=$_POST['public'];
    $data='some text to encrypt';
    $key = PublicKeyLoader::load($public);
    $key = $key->withPadding(RSA::ENCRYPTION_OAEP);
    $encoded=base64_encode($key->encrypt($data));
    header('Content-Type: application/json');
    echo json_encode(array('encrypted'=>$encoded));
    exit;
    }
    ?>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
    <script>
    jQuery(document).ready(function($) {
    function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint8Array(buf));
    }
    function str2ab(str) {
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
    var bufView = new Uint16Array(buf);
    for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
    }
    return buf;
    }
    function importPrivateKey(pem) {
    // fetch the part of the PEM string between header and footer
    const pemHeader = "-----BEGIN PRIVATE KEY-----\n";
    const pemFooter = "\n-----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: 1024,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: {name: "SHA-256"}
    },
    true,
    ["decrypt"]
    );
    }
    (async() => {
    let keyPair = await window.crypto.subtle.generateKey(
    {
    name: "RSA-OAEP",
    modulusLength: 1024,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: {name: "SHA-256"}
    },
    true,
    ["encrypt", "decrypt"]
    );

    var exported=await window.crypto.subtle.exportKey("pkcs8",keyPair.privateKey);
    var exportedAsString = ab2str(exported);
    var exportedAsBase64 = window.btoa(exportedAsString);
    var private = `-----BEGIN PRIVATE KEY-----\n${exportedAsBase64}\n-----END PRIVATE KEY-----`;

    var exported = await window.crypto.subtle.exportKey(
    "spki",
    keyPair.publicKey
    );
    var exportedAsString = ab2str(exported);
    var exportedAsBase64 = window.btoa(exportedAsString);
    var public = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;

    console.log(public);
    console.log(private);

    $.ajax({
    url:window.location,
    type:'POST',
    data:{
    public:public
    },
    success:function(data) {
    (async() => {
    console.log('*ENCRYPTED BY PHP*',data.encrypted);
    // HELP!!! NEED TO BE ABLE TO RELOAD THE KEY FROM ARMORED STRING
    var key=await importPrivateKey(private); // Error - Uncaught (in promise) DOMException
    var buffer=str2ab(window.atob(data.encrypted));
    // HELP!!! WONT DECRYPT WHAT PHP ENCODED USING THE PUBLIC KEY
    var decrypted=await window.crypto.subtle.decrypt({name:"RSA-OAEP"},key,buffer);

    console.log('DECRYPTED',decrypted);
    })();
    }
    });
    })();
    });
    </script>

    最佳答案

    该错误位于 str2ab()函数,它使用 Uint16Array而不是 Uint8Array .
    如果解决了这个问题,就可以导入私钥,解密用PHP代码生成的密文:

    function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint8Array(buf));
    }

    function str2ab(str) {
    // Fix: Don't double the size
    var buf = new ArrayBuffer(str.length);
    // Fix: Apply a Uint8Array!
    var bufView = new Uint8Array(buf);
    for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
    }
    return buf;
    }

    function importPrivateKey(pem) {

    const pemHeader = "-----BEGIN PRIVATE KEY-----\n";
    const pemFooter = "\n-----END PRIVATE KEY-----";
    const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);

    const binaryDerString = window.atob(pemContents);
    const binaryDer = str2ab(binaryDerString);

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

    (async function() {

    // Apply the private key from key pair generated with the posted JavaScript code
    var privateKey =
    `-----BEGIN PRIVATE KEY-----
    MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeQUdBu3zTX6QyfGfRWYxWWOnxd2xssTOIu6XczDByQEMfBbpQO9iM3u/Mn84zZFPFNvOKUNxcnftmrPiqUO9fBI2aAh77d2m65FBGsm4k/oUPzMNORGaDdBY4gg8FPMKo60kqBaMXAwzF8I4EUS/ot2fkBzSL0BGXT9o1NaO8bAgMBAAECgYAO2OPW8ywF86ervaFAHDN1YzVVdb+HXdqGJB/9tuE42q8R9BrHNbgrkLGvrveOoGGRrBCzhuyGubIsuVat0SqoI6qEnB9uahaIBfF5FZ7+bNW5OfkgerUUYP1S1MGFxUqINnUY1YHITmo6pUKHsiJtP7sihnCT6uEx8LqVNf1quQJBANs+VCZVUDq6eMy3E/u03HiAB8cyqLVMVQ4cLyoiWmFlnEFzZwMd20ZMjtcxICiizW3dlDvyxWYKH93irL0JyM0CQQDDp/VFsh83vKICVvM9IZHwE/Z8vZA3eTkGbWmgnr6qaxqge3FU02kUvIHHlvLmXYIt30lTq0Rn+Lz+TGV/jDeHAkBHYSaSiGojhLx5og1+gKbbEIv3vbWRuTVj76cnZ6HXXfaelIzwRdMzMw+6XgMjV8XcRCzTy7ma/Cbd3cPxk/LtAkEAwkehMVexz/KrHI+icG1JMI9iDnNdJPhmO4+hdzCqOyanBfwNiSF0Encslze4ci8f+NTjRwWlo2hGomzRzFk7OQJAPPd/o0azkg9nF+JxLiz7hF+/6MLVZgIfw04u05ANtOSVVQP4UTmJ/tNAe3OBUQVlRQAJ1m3jzUlir0ACPypC1Q==
    -----END PRIVATE KEY-----`;

    // Use the ciphertext generated with the PHP code
    var ciphertext = 'a8gEZ6/DymB8dTGPytQPNS8QiYFuUULK+/c0vtie1l722isC0Z/jSeC2ytA6MjVUuTdq7sPuNW850gEZ2XvKujLQzl9sjJ8pcsxznBzMK8v03YJCTBr2lbfHpEEtuSLaAR2UbovXDoCyIIvOnMjqlIS3Ug2PG4hALThn/aAUwE0=';

    var key = await importPrivateKey(privateKey);
    var decryptedBuffer = str2ab(window.atob(ciphertext));
    var decrypted = await window.crypto.subtle.decrypt(
    {name:"RSA-OAEP"},
    key,
    decryptedBuffer
    );

    console.log(ab2str(decrypted)); // some text to encrypt
    })();

    在这里,发布的 JavaScript 代码用于生成 RSA key 对。公钥:
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnkFHQbt801+kMnxn0VmMVljp8XdsbLEziLul3MwwckBDHwW6UDvYjN7vzJ/OM2RTxTbzilDcXJ37Zqz4qlDvXwSNmgIe+3dpuuRQRrJuJP6FD8zDTkRmg3QWOIIPBTzCqOtJKgWjFwMMxfCOBFEv6Ldn5Ac0i9ARl0/aNTWjvGwIDAQAB
    -----END PUBLIC KEY-----
    用于使用发布的 PHP 代码执行加密,私钥应用于上面的代码进行解密。

    关于javascript - RSA 加密、PHP 加密 (phpseclib) 和 JavaScript 解密 (crypto.subtle),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67346549/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com