【问题标题】:How to decrypt a string on OpenSSL that was previously encrypted via Crypto++?如何解密以前通过 Crypto++ 加密的 OpenSSL 上的字符串?
【发布时间】:2010-10-19 11:22:09
【问题描述】:

编辑:我发现钥匙不是我在 cmets 中所说的问题。我可以毫无问题地使用它们来加密和解密 OpenSSL 上的数据。

但我需要解密之前通过 Crypto++ 加密的 OpenSSL 上的字符串 这不起作用。

我稍后会发布更多详细信息。

您好,我已经使用 Crypto++ 生成的 RSA 公钥加密了一个字符串,现在我正在尝试(仍然不成功)通过 PHP 和 OpenSSL 对其进行解密。

这就是我正在做的:

  • 非 base64 或十六进制编码的私钥存储在名为“rsa-private.key”的文件中
  • 加密的消息存储在“message.txt”(十六进制编码)中

第一步:通过$key = file_get_contents("rsa-private.key");加载私钥

第 2 步:使用以下函数将密钥转换为 PEM 格式:

<?php
function pkcs8_to_pem($der) {

    static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----";
    static $END_MARKER = "-----END PRIVATE KEY-----";

    $value = base64_encode($der);

    $pem = $BEGIN_MARKER . "\n";
    $pem .= chunk_split($value, 64, "\n");
    $pem .= $END_MARKER . "\n";

    return $pem;
    }

    $PEMprivatekey = pkcs8_to_pem($key); 
?>

(stackoverflow.com/questions/1357569/)

第 3 步:准备密钥以供 OpenSSL 进一步使用:(没有任何问题)

<?php
$privateKey = openssl_get_privatekey($PEMprivatekey);
if (!$privateKey) {
    echo "Cannot get public key";
}
?>

第4步:获取消息并使用以下函数解码消息:

<?php
function hex_to_str($hex){

    for ($i=0; $i < strlen($hex)-1; $i+=2) {
    $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
    return $string;
}

$message = file_get_contents("message.txt");` 
$encryptedstring = hex_to_str($message);
?>

第 5 步:解密字符串:(不起作用)

<?php
openssl_private_decrypt($encryptedstring, $decrypteddata, $privateKey);
if (!$decrypteddata) {
    echo "........"; } else { echo $decrypteddata; }
?>

$decrypteddata 始终为空。

我不知道为什么它不起作用。有人注意到我做错了什么吗?

【问题讨论】:

  • 使用openssl_error_string查看是否有错误。您的第 4 步脚本有一个 `(但我猜它只是一个 SO 格式错误)
  • 哦,我完全忘记了。这就是我得到的:
  • error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
  • 错误:04065072:rsa 例程:RSA_EAY_PRIVATE_DECRYPT:填充检查失败
  • openssl_private_decrypt 更改padding 参数会改变什么吗? php.net/manual/en/function.openssl-private-decrypt.php

标签: php openssl rsa pem crypto++


【解决方案1】:

phpseclib 与 OpenSSL 完全可互操作,通常被认为更易于使用。以下 URL 提供了几个如何与 OpenSSL 互操作的示例:

RSA Encrypt in PHP to decrypt in .NET

【讨论】:

    【解决方案2】:

    好的,我不知道这是否是问题所在,但我想此时任何事情都有帮助。

    我创建了一个小的 openssl/php 测试脚本,并为测试提出了 2 个公钥-私钥对。

    openssl genrsa -des3 -out private.pem 1024
    openssl rsa -in private.pem -out public.pem -outform PEM -pubout
    
    openssl genrsa -out master.key 1024
    openssl rsa -in master.key -pubout -out master.pub
    

    第一对使用短语“短语”

    在这个脚本中使用这两个对来测试输出

    $source = "FAIL";
    echo "<pre>Source: $source";
    $fp=fopen("./keys/master.pub","r");
    $pub_key=fread($fp,8192);
    fclose($fp);
    openssl_get_publickey($pub_key);
    openssl_public_encrypt($source,$crypttext,$pub_key);
    echo "\n\nString crypted: $crypttext";
    flush();
    $fp=fopen("./keys/master.key","r");
    $priv_key=fread($fp,8192);
    fclose($fp);
    // phrase is required if your key is encoded (suggested)
    $res = openssl_get_privatekey($priv_key, 'phrase');
    openssl_private_decrypt($crypttext,$newsource,$res);
    while($error = openssl_error_string()) {
        echo "\n" , $error;
    }
    echo "\n\nString decrypt : $newsource";
    

    除了error:0906D06C:PEM routines:PEM_read_bio:no start line 错误消息之外一切正常

    但是当我混合键时(只是为了看看会创建什么错误消息)猜猜openssl_error_string 返回什么错误:

    error:0906D06C:PEM routines:PEM_read_bio:no start line
    error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
    error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed
    

    这样您就可以检查您的消息是否使用正确的公钥加密

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 2017-07-05
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      相关资源
      最近更新 更多