C# Rfc2898DeriveBytes是否等同于PKCS5_PBKDF2_HMAC_SHA1? C++中的rcc28 98派生字节和C++中的pkCS5pPBKDF2yHMACKOHAX1应该是相同的函数()。但是当我尝试加密C++中的一个消息并在C++中解密时,密码就不同了。我把相同的信息(密码、IV和salt)放在两面。我已经编译了一些简单的例子来说明发生了什么。我是在犯错误,还是我需要在其他地方使用不同的库

C# Rfc2898DeriveBytes是否等同于PKCS5_PBKDF2_HMAC_SHA1? C++中的rcc28 98派生字节和C++中的pkCS5pPBKDF2yHMACKOHAX1应该是相同的函数()。但是当我尝试加密C++中的一个消息并在C++中解密时,密码就不同了。我把相同的信息(密码、IV和salt)放在两面。我已经编译了一些简单的例子来说明发生了什么。我是在犯错误,还是我需要在其他地方使用不同的库,c#,c++,windows,unix,encryption,C#,C++,Windows,Unix,Encryption,c#加密: using System; using System.IO; using System.Text; using System.Security.Cryptography; public class RijndaelSimpleTest { [STAThread] static void Main(string[] args) { string plainText = "Hello, World!"; string passP

c#加密:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

public class RijndaelSimpleTest
{
    [STAThread]
    static void Main(string[] args)
    {
        string plainText  = "Hello, World!";
        string passPhrase = "testtesttesttesttesttest";
        string initVector = "6543210987654321";
        string saltValue  = "1234567890123456";
        int passwordIterations = 10000;
        int keySize = 32;

        byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations);
        byte[] keyBytes = password.GetBytes(keySize);
        string debugPassword = Convert.ToBase64String(keyBytes);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
        cryptoStream.FlushFinalBlock();
        byte[] cipherTextBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        string encyptText = Convert.ToBase64String(cipherTextBytes);
        string cipherText = initVector + saltValue + encyptText;

        Console.WriteLine(String.Format("Plaintext             : {0}", plainText));
        Console.WriteLine(String.Format("passPhrase            : {0}", passPhrase));
        Console.WriteLine(String.Format("initVector            : {0}", initVector));
        Console.WriteLine(String.Format("saltValue             : {0}", saltValue));
        Console.WriteLine(String.Format("passwordIterations    : {0}", passwordIterations));
        Console.WriteLine(String.Format("keySize               : {0}", keySize));
        Console.WriteLine(String.Format("password              : {0}", debugPassword));
        Console.WriteLine(String.Format("EncryptedText         : {0}", encyptText));
        Console.WriteLine(String.Format("EncryptedText+IV+SALT : {0}", cipherText));
    }
}
输出

Plaintext             : Hello, World!
passPhrase            : testtesttesttesttesttest
initVector            : 6543210987654321
saltValue             : 1234567890123456
passwordIterations    : 10000
keySize               : 32
password              : uu1FmPoEROlTBOvilXnIHG64uS56i3f4br/RZ1d49YE=
EncryptedText         : rVGIwm/WH9tw/SiN+iXw0Q==
EncryptedText+IV+SALT : 65432109876543211234567890123456rVGIwm/WH9tw/SiN+iXw0Q==
c++输出:

#include <openssl/evp.h>
#include <openssl/aes.h> 
#include <stdio.h> 
#include <string>
#include <iostream>

const unsigned char* convertString(const std::string& s){
    unsigned char * bytes = new unsigned char[s.size() + 1];
    std::copy(s.begin(), s.end(), bytes);
    bytes[s.size()] = '\0';
    return(bytes);
}

int main(int argc, char** argv) {
    const char  passPhrase[]        = "testtesttesttesttesttest";
    std::string ExpectedPlaintext   = "Hello, World!";
    int         passwordIterations  = 10000;
    int         keySize             = 32;
    std::string EncryptedText       = "65432109876543211234567890123456rVGIwm/WH9tw/SiN+iXw0Q==";
    std::string ExpectedIV          = "6543210987654321";
    std::string ExpectedSalt        = "1234567890123456";
    std::string ExpectedCipherText  = "rVGIwm/WH9tw/SiN+iXw0Q==";
    std::string Expectedpassword    = "uu1FmPoEROlTBOvilXnIHG64uS56i3f4br/RZ1d49YE=";
    const unsigned char *initVector = convertString(EncryptedText.substr(0,16));
    const unsigned char *saltValue  = convertString(EncryptedText.substr(16,16));
    const unsigned char *ciphertext = convertString(EncryptedText.substr(16+16));

    unsigned char password[keySize+16+1];
    if (PKCS5_PBKDF2_HMAC_SHA1(passPhrase, strlen(passPhrase),
                                    saltValue, strlen((char*)saltValue), passwordIterations,
                                    keySize+16, password) != 1) {
        std::cout << "Could not derive password" << std::endl;
        return -1;
    }
    password[keySize] = '\0';

    int p_len = keySize;
    int f_len = 0;
    unsigned char *plaintext = (unsigned char*)malloc(p_len + AES_BLOCK_SIZE);

    EVP_CIPHER_CTX d_ctx;
    EVP_CIPHER_CTX_init(&d_ctx);
    EVP_DecryptInit_ex(&d_ctx, EVP_aes_256_cbc(), NULL, password, initVector);
    EVP_DecryptInit_ex (&d_ctx, NULL, NULL, NULL, NULL);
    EVP_DecryptUpdate  (&d_ctx, plaintext, &p_len, ciphertext, keySize);
    EVP_DecryptFinal_ex(&d_ctx, plaintext+p_len, &f_len);
    keySize = p_len + f_len;

    std::cout << "EncryptedText     : " << EncryptedText << std::endl;
    std::cout << "passPhrase        : " << passPhrase << std::endl;
    std::cout << "passwordIterations: " << passwordIterations << std::endl;
    std::cout << "keySize           : " << keySize << std::endl;
    std::cout << "ExpectedIV        : " << ExpectedIV << std::endl;
    std::cout << "initVector        : " << initVector << std::endl;
    std::cout << "ExpectedSalt      : " << ExpectedSalt << std::endl;
    std::cout << "saltValue         : " << saltValue << std::endl;
    std::cout << "ExpectedCipherText: " << ExpectedCipherText << std::endl;
    std::cout << "ciphertext        : " << ciphertext << std::endl;
    std::cout << "Expectedpassword  : " << Expectedpassword << std::endl;
    std::cout << "password          : " << password << std::endl;
    std::cout << "ExpectedPlaintext : " << ExpectedPlaintext << std::endl;
    std::cout << "plaintext         : " << plaintext << std::endl;


    EVP_CIPHER_CTX_cleanup(&d_ctx);
    delete[] plaintext;
    delete[] initVector;
    delete[] saltValue;
    delete[] ciphertext;

    return 0;
}

<>你的C++代码中的问题是用你的代码>密文< /代码>变量:它是基础64数据。将其解码为二进制,然后尝试解密。

< P>你的C++代码中的问题与你的代码>密文< /代码>变量:它是基础64数据。在试图解密之前,将其解码为二进制。< /P>我给了你答案,下面是你的C++代码的一些注释:1。您使用
malloc
分配了
纯文本
,但使用
delete[]
取消分配了它。不要那样做。使用
malloc
分配的内存必须使用
free
释放。2:事实上,自行分配通常是错误的。改用类似于
std::vector
的容器。例如,从
convertString
函数返回一个原始指针(以后必须跟踪并
delete[]
),返回一个
std::vector
。当您与OpenSSL的C函数接口时,需要使用<代码>未签名的char */Cuff>,您这样做:<代码>和MyVo向量(0)< /C>。下面我给出了您的答案,但是这里有一些关于C++代码的注释:1。您使用
malloc
分配了
纯文本
,但使用
delete[]
取消分配了它。不要那样做。使用
malloc
分配的内存必须使用
free
释放。2:事实上,自行分配通常是错误的。改用类似于
std::vector
的容器。例如,从
convertString
函数返回一个原始指针(以后必须跟踪并
delete[]
),返回一个
std::vector
。当您与需要
无符号字符*
的OpenSSL的C函数交互时,您可以执行以下操作:
&myvector[0]
EncryptedText     : 65432109876543211234567890123456rVGIwm/WH9tw/SiN+iXw0Q==
passPhrase        : testtesttesttesttesttest
passwordIterations: 10000
keySize           : 16
ExpectedIV        : 6543210987654321
initVector        : 6543210987654321
ExpectedSalt      : 1234567890123456
saltValue         : 1234567890123456
ExpectedCipherText: rVGIwm/WH9tw/SiN+iXw0Q==
ciphertext        : rVGIwm/WH9tw/SiN+iXw0Q==
Expectedpassword  : uu1FmPoEROlTBOvilXnIHG64uS56i3f4br/RZ1d49YE=
password          : ºíEúDéSëâyÈn¸¹.zwøn¿ÑgWxõ
ExpectedPlaintext : Hello, World!
plaintext         : ÊÁMþ±B¯ÍN'¤ä+èû~OÂ(H¢