首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP使用appkey对加密的sek进行解密

PHP使用appkey对加密的sek进行解密
EN

Stack Overflow用户
提问于 2020-11-11 23:00:52
回答 1查看 174关注 0票数 1

我正在尝试使用PHP的eInvoice API。在我收到authkey生成后,我需要使用appkey来解密加密的sek。我有以下代码

代码语言:javascript
运行
复制
$key = openssl_random_pseudo_bytes(16);
$AppKey = Encrypt($key, $bob_public_key);

var_dump(DecryptBySymmetricKey($sek, $key));

function Encrypt($appKey, $Publickey)
{
    openssl_public_encrypt($appKey, $encrypted, $Publickey);
    return base64_encode($encrypted);
}
function DecryptBySymmetricKey($encrypted_string, $encryption_key) {
    $cipher     = 'AES-256-CBC';
    $options    = OPENSSL_RAW_DATA;
    $hash_algo  = 'sha256';
    $sha2len    = 32;
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = substr($encrypted_string, 0, $ivlen);
    $hmac = substr($encrypted_string, $ivlen, $sha2len);
    $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
    
    $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
    
    $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
    
    if(function_exists('hash_equals')) {
        if (hash_equals($hmac, $calcmac)) return $original_plaintext;
    } else {
        if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
    }
}

但这并没有返回解密文本。它总是返回NULL。你能在这方面请任何人帮我一下吗?

EN

回答 1

Stack Overflow用户

发布于 2020-11-13 02:53:54

由于您希望使用AppKey解密SEK,因此部分中的Java代码,即方法decrptyBySyymetricKey()是相关的(文档中已经有输入错误)。此代码在功能上与发布的PHP代码不同(例如,关于模式、MAC等)。在功能上与Java代码相同的PHP实现如下:

代码语言:javascript
运行
复制
<?php
function DecryptBySymmetricKey($encryptedSek, $appKey) {
    $sek = openssl_decrypt($encryptedSek, 'aes-256-ecb', $appKey, 0);
    return base64_encode($sek);
}

// Test
// $appKey = openssl_random_pseudo_bytes(32);
$appKey = hex2bin('b42b0df750c207f0288cced8d89976431c43247ba45b64bf3ef0ed9325f9fb16'); // test key for comparison with C# code
$encryptedSek = 'RwDmJm/OBNW8bVTISa7nmOuMiixp9blBM0g3S0v7h1OKZ9SMJGlg0DVpARRyLadH';
$decryptedSek = DecryptBySymmetricKey($encryptedSek, $appKey);
print($decryptedSek . PHP_EOL); // MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDE=
?>

下面的Java代码使用decrptyBySyymetricKey()返回相同的结果

代码语言:javascript
运行
复制
byte[] appKey = Hex.decodeHex("b42b0df750c207f0288cced8d89976431c43247ba45b64bf3ef0ed9325f9fb16"); // test key for comparison with PHP code
String encryptedSek = "RwDmJm/OBNW8bVTISa7nmOuMiixp9blBM0g3S0v7h1OKZ9SMJGlg0DVpARRyLadH";
String decryptedSek = decrptyBySyymetricKey(encryptedSek, appKey);  
System.out.println(decryptedSek); // MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDE=

因此,这两种实现在功能上是相同的。

请注意,decrptyBySyymetricKey()将应用于Base64 en-/解码。Hex.decodeHex()也来自这个库。

另请注意,根据文档(请参阅eInvoice站点上的 ),并且与AES-256一致,当您使用16字节密钥时,AppKey必须是32字节密钥,即它必须:

代码语言:javascript
运行
复制
$appKey = openssl_random_pseudo_bytes(32);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64788866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档