簡體   English   中英

OPENSSL Blowfish CBC加密不同於PHP到C ++

[英]OPENSSL Blowfish CBC encryption differs from PHP to C++

我試圖在兩者中使用OPENSSL庫加密和解密C ++庫和PHP服務器之間的通信。 我想使用Blowfish CBC算法,但似乎C ++代碼和PHP代碼之間的結果不同。 C ++代碼取自這里:

這是PHP代碼:

<?php
function strtohex($x) 
{
    $s='';
    foreach (str_split($x) as $c) $s.=sprintf("%02X",ord($c));
    return($s);
} 


$encryptedMessage = openssl_encrypt("input", "BF-CBC", "123456", 0, "initvect");


echo $encryptedMessage;
echo "\n";
echo strtohex($encryptedMessage);

PHP輸出是這樣的:

x9jDa2WMwvQ=
78396A446132574D7776513D

這是c ++代碼:

bool do_encrypt(const char *in, unsigned char *out, int *outlen, unsigned    char *key, unsigned char *iv)
{
    int buflen, tmplen;

    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), nullptr, key, iv);

    if (!EVP_EncryptUpdate(&ctx, out, &buflen, (unsigned char*)in,     strlen(in)))
    {
        return false;
    }

    if (!EVP_EncryptFinal_ex(&ctx, out + buflen, &tmplen))
    {
        return false;
    }

    buflen += tmplen;
    *outlen = buflen;
    EVP_CIPHER_CTX_cleanup(&ctx);

    return true;
}

unsigned char output[2048] = { 0 };
int outLen;

auto result = do_encrypt("input", output, &outLen, (unsigned char*)"123456", (unsigned char*)"initvect");

BIGNUM *outputStr = BN_new();
BN_bin2bn(output, outLen, outputStr);

cout << base64_encode(output, outLen) << "\n";
cout << BN_bn2hex(outputStr) << "\n";

C ++輸出是這樣的:

 EfRhhWqGmSQ=
 11F461856A869924

有人可以幫我理解我做錯了什么嗎? 任何幫助將非常感謝。

謝謝!

編輯1:我設法在jww的答案之后修復C ++代碼並且運行良好。 我錯過了EVP_CIPHER_CTX_set_key_length但是,我無法使PHP代碼返回相同的東西,最終我們決定轉向AES,它現在可以完美運行。 謝謝!

對於您的OpenSSL代碼,我認為您需要調用EVP_CIPHER_CTX_set_key_length來告訴庫密鑰只有6個字節。

讓我把Crypto ++扔進下面的競技場。 添加缺少的EVP_CIPHER_CTX_set_key_length OpenSSL調用后,OpenSSL和Crypto ++將收斂於正確的答案。 正確答案是32CEBA7E046431EB (十六進制)。

我不知道PHP發生了什么:

x9jDa2WMwvQ=
78396A446132574D7776513D

考慮到x是ASCII 0x78, 9是ASCII 0x39,我猜你的十六進制編碼的Base64編碼字符串。


$ cat test.cxx
#include "blowfish.h"
#include "modes.h"
#include "channels.h"
#include "filters.h"
#include "base64.h"
#include "hex.h"
using namespace CryptoPP;

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
  const byte key[] = "123456";   // 6
  const byte  iv[] = "initvect"; // 8
  CBC_Mode<Blowfish>::Encryption encryptor;
  encryptor.SetKeyWithIV(key, 6, iv, 8);

  string r1, r2;
  ChannelSwitch chsw;

  Base64Encoder e1(new StringSink(r1));
  HexEncoder e2(new StringSink(r2));
  chsw.AddDefaultRoute(e1);
  chsw.AddDefaultRoute(e2);

  string msg = "input";
  StringSource ss(msg, true,
    new StreamTransformationFilter(encryptor,
      new Redirector(chsw)));

  cout << r1 << endl;
  cout << r2 << endl;

  return 0;
}

測試程序導致:

$ ./test.exe
Ms66fgRkMes=
32CEBA7E046431EB

這是OpenSSL的一部分。 注意EVP_EncryptInit_ex被調用兩次。 首先,調用EVP_EncryptInit_ex來設置塊密碼EVP_bf_cbc 密鑰長度使用EVP_CIPHER_CTX_set_key_length設置。 然后,調用EVP_EncryptInit_ex來設置密鑰和iv。

#include <openssl/evp.h>

#include <iostream>
#include <iomanip>
#include <stdexcept>
using namespace std;

typedef unsigned char byte;

int main()
{
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);

  int rc;
  const byte key[] = "123456";   // 6
  const byte  iv[] = "initvect"; // 8

  rc = EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, 0, 0);
  if (rc != 1)
    throw runtime_error("EVP_EncryptInit_ex failed");

  rc = EVP_CIPHER_CTX_set_key_length(&ctx, 6);
  if (rc != 1)
    throw runtime_error("EVP_CIPHER_CTX_set_key_length failed");

  rc = EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv);
  if (rc != 1)
    throw runtime_error("EVP_EncryptInit_ex failed");

  const byte msg[] = "input";
  byte buf[32];
  int len1 = sizeof(buf), len2 = sizeof(buf);

  rc = EVP_EncryptUpdate(&ctx, buf, &len1, msg, 5);
  if (rc != 1)
    throw runtime_error("EVP_EncryptUpdate failed");

  rc = EVP_EncryptFinal_ex(&ctx, buf+len1, &len2);
  if (rc != 1)
    throw runtime_error("EVP_EncryptFinal_ex failed");

  for(unsigned int i=0; i<len1+len2; i++)
      cout << std::hex << setw(2) << setfill('0') << (int)buf[i];
  cout << endl;

  EVP_CIPHER_CTX_cleanup(&ctx);
  return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM