gpt4 book ai didi

javascript - phpseclib 未验证在 window.subtlecrypto 中生成的签名

转载 作者:行者123 更新时间:2023-12-04 10:53:45 27 4
gpt4 key购买 nike

所以是的,我的老板想将加密放入他的系统,他希望消息以 js 签名并在 php 中验证。目前,我正在使用 mozilla 的 tinycrypto api 生成 RSA-PSS key 并签名和 phpseclib 进行验证。问题是,它没有。

使用js key ,phpseclib可以签名验证就好了,但是不能处理js签名。

这是我的代码。
JS:

    function keys(){
var cryptoObj = window.crypto || window.msCrypto;
let msg = '///';
if(!cryptoObj)
{
alert("Crypto API is not supported by the Browser");
return;
}

window.crypto.subtle.generateKey({
name: "RSA-PSS",
modulusLength: 2048, //can be 1024, 2048, or 4096
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
true, //whether the key is extractable (i.e. can be used in exportKey)
["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key) {
publicKey = key.publicKey;
privateKey = key.privateKey;
// For Demo Purpos Only Exported in JWK format
if (document.getElementById('public').value == "") {
window.crypto.subtle.exportKey("spki", key.publicKey).then(
function (keydata) {
publicKeyhold = keydata;
let exported = publicKeyhold;
const exportedAsString = ab2str(exported);
const exportedAsBase64 = window.btoa(exportedAsString);
const pemExported = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;
document.getElementById('public').value = pemExported;
}
);
}

if (document.getElementById('private').value == "" ) {
msg = document.getElementById('msg').value;
window.crypto.subtle.exportKey("pkcs8", key.privateKey).then(
function (keydata) {
privateKeyhold = keydata;
const priv = privateKeyhold;
const privExportedAsString = ab2str(priv);
const privExportedAsBase64 = window.btoa(privExportedAsString);
const privPemExported = `-----BEGIN RSA PRIVATE KEY-----\n${privExportedAsBase64}\n-----END RSA PRIVATE KEY-----`;
document.getElementById('privJSON').data = key.privateKey;
document.getElementById('private').value = privPemExported;
}
);
}})
window.crypto.subtle.sign({
name: "RSA-PSS",
saltLength: 128, //the length of the salt
},
//from generateKey or importKey above
document.getElementById('privJSON').data,
getMessageEncoding())
//ArrayBuffer of data you want to sign
.then(function(signature) {
//returns an ArrayBuffer containing the signature
console.dir(ab2str(signature));
document.getElementById("cryptmsg").value = window.btoa(ab2str(signature)) ;
})


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


function asciiToUint8Array(str) {
var chars = [];
for (var i = 0; i < str.length; ++i)
chars.push(str.charCodeAt(i));
return new Uint8Array(chars);
}

function bytesToHexString(bytes) {
if (!bytes)
return null;

bytes = new Uint8Array(bytes);
var hexBytes = [];

for (var i = 0; i < bytes.length; ++i) {
var byteString = bytes[i].toString(16);
if (byteString.length < 2)
byteString = "0" + byteString;
hexBytes.push(byteString);
}

return hexBytes.join("");
}
function getMessageEncoding() {
const messageBox = document.getElementById('msg');
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}

php:
<?php
include('Crypt/RSA.php');
define('CRYPT_RSA_PKCS15_COMPAT', true);

$pubK = $_POST['public'];
$privK = $_POST['private'];
echo $pubK."<br><br>";
echo $privK."<br><br>";

$sign = ($_POST['cryptmsg']);
$txt = $_POST['msg'];

$rsa = new Crypt_RSA();

$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PSS);
$rsa->setSaltLength(128);
$rsa->setMGFHash("SHA256");
$rsa->setHash("SHA256");

$rsa->loadKey($privK);
$serverSign = $rsa->sign($txt);

$rsa->loadKey($pubK);
echo "text: ".$txt;
echo "<br><br>js sign: <br>".($sign)."<br><br>";
echo "seclib sign: <br>".base64_encode($serverSign);
echo "<br><br>";

$jsTest = $rsa->verify($txt, base64_decode($sign)) ? 'verified' : 'unverified';
$selfTest = $rsa->verify($txt, $serverSign) ? 'verified' : 'unverified';

echo 'js signature: '. $jsTest;
echo'<br> phpseclib signature (same keys): '. $selfTest;

最佳答案

在 PHP 代码中,摘要必须用 sha256 指定。 , 即用小写字母代替大写字母:

$rsa->setMGFHash("sha256");
$rsa->setHash("sha256");
phpseclib不知道大写名称,因此使用默认摘要 sha1相反, [1] .这可以通过输出与 $rsa->hashName 一起使用的摘要的名称来轻松测试。 .

这个错误不是那么容易找到,如果 phpseclib 可能会更好会显示错误消息或警告而不是静默使用默认值。

附带说明:在 JavaScript 代码中,私钥以 PKCS8 格式导出,但使用 PKCS1 格式的页眉和页脚, [2] .然而, phpseclib容忍这种不一致。

关于javascript - phpseclib 未验证在 window.subtlecrypto 中生成的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331626/

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