在 PHP 中模拟 WebCrypto RSA-OAEP 加密 [英] simulate WebCrypto RSA-OAEP encryption in PHP

查看:192
本文介绍了在 PHP 中模拟 WebCrypto RSA-OAEP 加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个使用 RSA-OAEP 从客户端接收数据的服务器.

We have a server which is using RSA-OAEP to receive data from client.

我无权访问服务器,检查结果的唯一方法是发送请求并检查其回复.

I don't have access to server and the only way to check my result is to send a request and check its reply.

我已经能够使用 WebCrypto 发送正确的请求,但我没有使用 php 成功.

I've been able to send correct request with WebCrypto but I didn't have any success with php.

我用于 JS 的代码:

the code I'm using for JS :

var DataToEncrypt = 'abcd';
var pemEncodedKey = `-----BEGIN PUBLIC KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END PUBLIC KEY-----`;
let encryptionKey;
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;
}

function importPublicKey(pem) {
    const pemHeader = "-----BEGIN PUBLIC KEY-----";
    const pemFooter = "-----END PUBLIC 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(
        "spki",
        binaryDer,
        {
            name: "RSA-OAEP",
            hash: "SHA-256"
        },
        true,
        ["encrypt"]
    );
}

function getMessageEncoding() {
    const enc = new TextEncoder();
    return enc.encode(DataToEncrypt);
}
async function encryptMessage() {
    const encoded = getMessageEncoding();
    const ciphertext = await window.crypto.subtle.encrypt(
        {
            name: "RSA-OAEP"
        },
        encryptionKey,
        encoded
    );

    var decoder = new TextDecoder('utf8');
    var b64encoded = btoa(String.fromCharCode.apply(null, new Uint8Array(ciphertext)));
    document.getElementById('crypt').value = b64encoded;
}

document.getElementById('import').addEventListener("click", async () => {
    encryptionKey = await importPublicKey(pemEncodedKey);
});

document.getElementById('encrypt').addEventListener("click", function(){
    encryptMessage();
});

这是我的 php 函数(使用 phpseclib):

and this is my php function (using phpseclib) :

function encrypt($data) {
    $key = '-----BEGIN PUBLIC KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END PUBLIC KEY-----';

    $rsa = new Crypt_RSA();
    $rsa->setHash('sha256');
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
    $rsa->loadKey($key); // public key
    $crypted = $rsa->encrypt($data);

    return base64_encode($crypted);
}
echo encrypt('abcd');

我尝试了这两种方法,结果都向服务器发送请求,正如我之前提到的,只有 js 代码有效,而 php 输出没有按预期工作.

I tried both of these methods result to send a request to server and as I mentioned earlier only js code works and php output does not work as expected.

推荐答案

我尝试使用我生成的一对公钥/私钥使用 js 加密某些内容并使用 php (phpseclib) 对其进行解密,并且成功了.

I tried to encrypt something with js and decrypt it with php (phpseclib) using a pair of public/private keys which I produced and it was successful.

在那之后,我尝试将我的公钥重新格式化为每行 64 个字符(它与 js 中的一样在一行中)并同时使用 setHash('sha256') 和 setMGFHash('sha256'),现在我的php 函数有效.

After that I tried to reformat my public key to 64 chars in each line (it was in a single line like the one in js) and used both setHash('sha256') and setMGFHash('sha256') and now my php function works.

新的php函数:

function encrypt($data)
{
    $key = '-----BEGIN PUBLIC KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX
-----END PUBLIC KEY-----';

    $rsa = new Crypt_RSA();
    $rsa->setHash('sha256');
    $rsa->setMGFHash('sha256');
    $lk = $rsa->loadKey($key); // public key
    $crypted = $rsa->encrypt($data);
    return base64_encode($crypted);
}

这篇关于在 PHP 中模拟 WebCrypto RSA-OAEP 加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆