php - Nodejs加密签名,php验证签名

标签 php node.js rsa phpseclib php-openssl

我想在nodejs中对某些数据进行加密和签名,并在php中验证签名。我不断收到此错误:

error:04091077:rsa routines:int_rsa_verify:wrong signature length

我尝试更改正在使用的算法,还尝试了 php 扩展,例如 phpseclib。在 Nodejs 中,我使用 "crypto": "^1.0.1"。还有 php 中的 openssl_verify。

这是我的nodejs代码

const crypto = require('crypto');

module.exports = {

    generateKey: () => {


    return   { publicKey, privateKey } = generateKeyPairSync('rsa', {
            modulusLength: 2048,
            publicKeyEncoding: {
                type: 'spki',
                format: 'pem'
            },
            privateKeyEncoding: {
                type: 'pkcs8',
                format: 'pem',

            }

      });
    },

    encryptMessage: (message) => {
        const config = new Configstore(packageJson.name);
        const algorithm = 'aes-256-cbc';
        const key = config.get('serverKey');
        const iv = crypto.randomBytes(16);
        let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv);
        let encrypted = cipher.update(message);
        encrypted = Buffer.concat([encrypted, cipher.final()]);

        return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex')};

    },

    signMessage: (message) => {
        console.log(message);
        const config = new Configstore(packageJson.name);
        const sign = crypto.createSign('SHA256');
        sign.update(message);
        sign.end();
        const signature = sign.sign(config.get('privateKey'),'base64');

        const verify = crypto.createVerify('SHA256');
        verify.update(message);
        verify.end();
        console.log(config.get('publicKey'));
        console.log('Its working: ' + verify.verify(config.get('publicKey'), signature, 'base64'));
        return signature;
    }

}

这是 php:

public function saveSecreteMessage(Request $request) {

        $request->validate([
            'username' => 'required',
            'secretName' => 'required',
            'secretMessage' => 'required'
        ]);

        $publicKey = User::where('username', $request->input('username'))->first();

        if (!$publicKey) {
            return response()->json('Not allowed', 401);
        }

        $data = $request->input('secretMessage')['encryptedData'];
        $signature = $request->input('secretMessage')['signature'];

    /*    $rsa = new RSA();
        $rsa->loadKey($publicKey->publicKey); // public key;
        return $rsa->verify('message', $signature, 'base64') ? 'verified' : 'unverified';*/

        $ok = openssl_verify(base64_encode($data),  base_path($signature), $publicKey->publicKey, 'SHA256');

        if ($ok == 1) {
            return response()->json('', 200);
        } else {
            return response()->json(openssl_error_string(), 400);
        }

        $pet = $request->all();
        return $pet;
    }

我希望 php 代码能够验证从 nodejs 发送过来的签名。我似乎无法让它发挥作用。我得到的错误是:

error:04091077:rsa routines:int_rsa_verify:wrong signature length

最佳答案

我成功了。

JS代码:

const crypto = require('crypto');

keyPair = crypto.generateKeyPairSync('rsa', {
            modulusLength: 2048,
            publicKeyEncoding: {
                type: 'spki',
                format: 'pem'
            },
            privateKeyEncoding: {
                type: 'pkcs8',
                format: 'pem',

            }

      });

var message = "zzzz";

const sign = crypto.createSign('SHA256');
sign.update(message);
sign.end();

const signature = sign.sign(keyPair.privateKey,'base64');

console.log(keyPair.publicKey);
console.log(signature);

PHP 代码:

$rsa = new RSA;
$rsa->loadKey('-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1e4Gi38Dlyl41RSGnQAK
UsHONpX806tFD3fuOby3JQlhlDM+Pe/H8y6E/zMDtNSZXtO+QCqghtMLDVG2br9e
i8uvGFwxLFUaWVkOYY7Tz21vJYYclvn67y0fJE8jgKUOdl3fgv/H3IGRVTROOetH
4oMpHMTGRpjZFfI6mi7CSDiaR8D1EpmPeXJn8yYPHK4uDn5srhZDQTvXXwbYkskX
FjbSx3yKvu1wkwKbKU5GkbBCzsFlNDhlCN4fvZ9SjinnV1iARgB80qIQlQ6JAUpp
xM/bTUntjI73DHCF3dXv9pbwn6w/vfjoyxstwAzgp+7C8HuaVm12KOeKG5Lsbj/L
XwIDAQAB
-----END PUBLIC KEY-----');

$plaintext = 'zzzz';
$signature = base64_decode('Vzc+63A5nAZWwIPD99pJQkzR7JfOhG0xyaTQh+Pel2wWklnzN9lTibwhliJs7tyZlJzjZrhgS2reTDd26HqLw11RDbqMCxim/InOiuFPbOg8EgNt55mNyfICszt+2ZVa1Mjm8zXpFBvNee5EPPFbqoCRKUpulDiGwRVz8v6rgSrx+Ptl11dIXyQuTa90bTdJEHiGK73F/uPh/B9AQOVYkoJKA4GC8H7pC3+AiTBREeBfRZp7gMF3wq2pYS5ffGemxsIkKuVoDurVNSJL9xWF10H3nn0egpIDwDQLYdilrVAUW7z+Qu6lQ2FxNiFSX0TT6gL02WN5/UxCVokCSnufkg==');

$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$rsa->setHash('sha256');

echo $rsa->verify($plaintext, $signature) ? 'good' : 'bad';

关于php - Nodejs加密签名,php验证签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57401046/

相关文章:

java - 为什么 Java 无法加载此类 : com. android.org.conscrypt.OpenSSLRSAPublicKey

php - mysql中的日期格式,如何进行转换查询?

javascript - 使用 Crypto Node.js 获取错误 "data too large for key size"

java - 如何使用模数和指数/公钥快速破解 Java 中大量数字的 RSA 加密

node.js - node_redis 回调参数

node.js - 如何在具有 yarn 工作空间的 monorepo 中从 nodejs 项目构建 docker 镜像

javascript - 使用 Puppeteer 时等待文本出现

php - 避免使用 php 显示具有 Null 值的行

php - 如何在网站内为每个页面动态包含不同的元标记,以便在 Google 搜索中看到

php - MariaDB 避免死锁