解密工作使用 PHP (openssl) 而不是使用 javascript (cryptojs)

如何解决解密工作使用 PHP (openssl) 而不是使用 javascript (cryptojs)

解密使用 PHP/openssl 工作,我可以获得我的纯数据。这是定义的调用

<?PHP

function decryptString($data,$key)
{
    return base64_decode(openssl_decrypt(base64_decode($data),"AES-256-CBC",$key,true,"h7oehNIHWGNIHxyN"));
}

function encryptString($data,$key)
{
    return base64_encode(openssl_encrypt(base64_encode($data),"h7oehNIHWGNIHxyN"));
}

echo 'encrypted: ' . encryptString('my sample text','7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";

echo 'decrypted: ' . decryptString('rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=','7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";

我得到这个输出

encrypted: rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=
decrypted: my sample text

我尝试使用 cryptojs 来实现同样的功能,但事情并没有奏效,我有时会收到“格式错误的 UTF-8 数据”,有时还有其他不明确的错误(空字符串/无法读取属性长度为未定义取决于我所做的代码更改)。所以这是迄今为止我做的最好的:(我目前有“格式错误的 UTF-8 数据”错误

function decryptData(encrypted,pass) {
    // encrypted is a base64 encoded string
    let data = let data = Buffer.from(encrypted,"base64").toString();  // I tried this also [ let data = crypto.enc.Base64.parse(encrypted); ]

    let key = crypto.enc.Utf8.parse(pass);
    let decrypted = crypto.AES.decrypt(data,key,{
            iv: crypto.enc.Hex.parse('h7oehNIHWGNIHxyN'),// tried passing it as a simple string like this [ iv: 'h7oehNIHWGNIHxyN',]
            mode: crypto.mode.CBC,padding: crypto.pad.nopadding // I tried also with [ crypto.pad.Pkcs7 ]
        }
    );
let result =  decrypted.toString(crypto.enc.Utf8); //  tried this also [ let result = decrypted.toString(crypto.enc.Base64) ]
}

这是我得到的错误

/home/vagrant/PHPstormProjects/untitled3/node_modules/crypto-js/core.js:513
                    throw new Error('Malformed UTF-8 data');
                    ^

Error: Malformed UTF-8 data
    at Object.stringify (/home/vagrant/PHPstormProjects/untitled3/node_modules/crypto-js/core.js:513:24)
    at WordArray.init.toString (/home/vagrant/PHPstormProjects/untitled3/node_modules/crypto-js/core.js:268:38)
    at decodeBase64String (/home/vagrant/PHPstormProjects/untitled3/decryptor.js:13:25)
    at Object.<anonymous> (/home/vagrant/PHPstormProjects/untitled3/decryptor.js:19:1)

这可能看起来很明显,但我感到困惑,似乎没有任何效果。你能帮我吗?

我尝试回答但没有成功的问题:

更新 1: 我编辑了问题以添加示例纯消息和完整的 PHP 加密/解密示例以及我的上一个代码版本。

解决方法

AES 仅针对 16/24/32 字节密钥定义。您正在使用 40 字节的密钥。 PHP 隐式地将密钥削减为 32 个字节,CryptoJS 没有,但由于错误 (#293) 处理密钥而没有错误消息,当然结果是错误的。
此外,密文必须作为CipherParams对象或Base64编码传递,IV必须是Utf8编码,应该使用PKCS7填充,并且解密数据是一个base64字符串(并且仍然需要Base64解码)。

以下 CryptoJS 代码对示例密文进行解密:

function decryptData(encrypted,pass) {

    let decryptedWA = CryptoJS.AES.decrypt(
        encrypted,// Pass ciphertext Base64 encoded (or as CipherParams object)
        CryptoJS.enc.Utf8.parse(pass.substring(0,32)),// Truncate key to 32 bytes
        {
            iv: CryptoJS.enc.Utf8.parse('h7oehNIHWGNIHxyN'),// UTF8 encode the IV 
            mode: CryptoJS.mode.CBC,// default
            padding: CryptoJS.pad.Pkcs7 // default              // Apply PKCS7 padding
        }
    );

    let decryptedB64 =  decryptedWA.toString(CryptoJS.enc.Utf8); 
    let decrypted = CryptoJS.enc.Base64.parse(decryptedB64).toString(CryptoJS.enc.Utf8); // Base64 decode the decrypted data

    return decrypted;
}

var ciphertext = "rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=";
var key = "7f7720b911c2ecbb22637ed7adef41e82d44b6a0";
console.log(decryptData(ciphertext,key));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

请注意,静态 IV 是不安全的(但也许您仅将静态 IV 用于测试目的)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?