jjzjj

aes - 从 C++ 代码和命令行生成相同的 key 和 IV

coder 2024-02-22 原文

我的命令行工具 openssl 有问题,或者我的 C++ 代码有问题。我不知道哪个是不正确的,但是当我使用这两种方法从密码阶段和盐生成 key 和 IV 时,我没有得到相同的 key /IV 值。您看到的代码或命令行是否有任何拼写错误或问题?是不是openssl 0.9.8i的版本坏了?我使用的 nround 值为 1,因为命令行无法传递迭代计数值。它应该是匹配的,但它不是,我无法发现我的错误在哪里。

-----------------The following code encrypts the string XYZ correctly as 2OG7CNt/SjFEZ4RM3ZS4ZA== with Key: eaa4d33f9f6a9a8e543c0ae80eef651b675ef50682e5f144f1c140269531ddb2 IV: e94c989252a82fcb6b934752c0f3702b ----

EVP_CIPHER_CTX ctx;
unsigned char acOutbuf[cMaxEncryptLen + EVP_MAX_BLOCK_LENGTH + 1];
int nOutLen;
std::string strDecrypt;

// Key and IV values.
const unsigned char pcCode[] = "f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8";
const unsigned char pcSalt[] = {0x78,0x01,0x3E,0x00,0xD8,0x04,0x3E,0x00};
unsigned char acKey[EVP_MAX_KEY_LENGTH + 1];
unsigned char acIV[EVP_MAX_IV_LENGTH + 1];

// Load all the encryption ciphers and lookup the one we want to use.
OpenSSL_add_all_algorithms();
const EVP_CIPHER *cipher = EVP_get_cipherbyname("aes-256-cbc");

// Generate HashKey for the password.
int nrounds = 1;
int nCnt = EVP_BytesToKey(cipher, EVP_sha1(), pcSalt, pcCode, sizeof(pcCode), nrounds, acKey, acIV);

char *pcPassword = const_cast<char *> (strPassword.c_str());
nBase64DecodeCnt = strPassword.length();

EVP_CIPHER_CTX_init(&ctx);

EVP_CipherInit_ex(&ctx, cipher, NULL, acKey, acIV, 1);
if(!EVP_CipherUpdate(&ctx, acOutbuf, &nOutLen, (const unsigned char *) pcPassword, nBase64DecodeCnt))
{
    EVP_CIPHER_CTX_cleanup(&ctx);
    return strDecrypt;
}
if(!EVP_CipherFinal_ex(&ctx, acOutbuf, &nOutLen))
{
    EVP_CIPHER_CTX_cleanup(&ctx);
    return strDecrypt;
}

strDecrypt.assign((const char *) acOutbuf, nOutLen);

EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;

----------------下面的代码将2OG7CNt/SjFEZ4RM3ZS4ZA==解密为XYZ ------------------ ----

EVP_CIPHER_CTX ctx;
unsigned char acOutbuf[cMaxEncryptLen + EVP_MAX_BLOCK_LENGTH + 1];
int nOutLen;
std::string strDecrypt;

// Key and IV values.
const unsigned char pcCode[] = "f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8";
const unsigned char pcSalt[] = {0x78,0x01,0x3E,0x00,0xD8,0x04,0x3E,0x00};
unsigned char acKey[EVP_MAX_KEY_LENGTH + 1];
unsigned char acIV[EVP_MAX_IV_LENGTH + 1];

// Load all the encryption ciphers and lookup the one we want to use.
OpenSSL_add_all_algorithms();
const EVP_CIPHER *cipher = EVP_get_cipherbyname("aes-256-cbc");

// Generate HashKey for the password.
int nrounds = 1;
int nCnt = EVP_BytesToKey(cipher, EVP_sha1(), pcSalt, pcCode, sizeof(pcCode), nrounds, acKey, acIV);

// Convert the base64 password string back into a real password.
int nBase64DecodeCnt;
char *pcPassword = Base64ToByteStream ((char *) strPassword.c_str(), (int) strPassword.length(), &nBase64DecodeCnt);

EVP_CIPHER_CTX_init(&ctx);

EVP_CipherInit_ex(&ctx, cipher, NULL, acKey, acIV, 0);
if(!EVP_CipherUpdate(&ctx, acOutbuf, &nOutLen, (const unsigned char *) pcPassword, nBase64DecodeCnt))
{
    EVP_CIPHER_CTX_cleanup(&ctx);
    return strDecrypt;
}
if(!EVP_CipherFinal_ex(&ctx, acOutbuf, &nOutLen))
{
    EVP_CIPHER_CTX_cleanup(&ctx);
    return strDecrypt;
}

strDecrypt.assign((const char *) acOutbuf, nOutLen);

EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;

请注意,虽然我可以使用 openssl 命令行工具进行解密和加密,但我似乎无法使用命令行正确生成 key 和 iv。

---- Encrypts correct -----
echo -n XYZ | openssl enc -e -a -aes-256-cbc -K eaa4d33f9f6a9a8e543c0ae80eef651b675ef50682e5f144f1c140269531ddb2 -iv e94c989252a82fcb6b934752c0f3702b

Produces : 2OG7CNt/SjFEZ4RM3ZS4ZA==

---- Decrypts correct to XYZ ----

echo 2OG7CNt/SjFEZ4RM3ZS4ZA== | openssl.exe enc -d -a -aes-256-cbc -K eaa4d33f9f6a9a8e543c0ae80eef651b675ef50682e5f144f1c140269531ddb2 -iv e94c989252a82fcb6b934752c0f3702b

Produces : XYZ

-----  Does not produce the correct key and IV --------
openssl enc -aes-256-cbc -md sha1 -S 78013E00D8043E00 -P -pass pass:f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8

salt=78013E00D8043E00
key=718D65A221F0B2F12B6C92B7E54501DD63A8E156E03CA0E98E73653B1D0F58E5
iv =A5FDF910766E727E2100FA09B7578685

最佳答案

openssl 命令行工具似乎使用了字符指针和字符串长度。我正在使用一个字符数组和字符数组的大小。这从我的计算中遗漏了最后一个 '\0' 字符,导致我生成不同的键和 IV 值。更正后的代码是:

{
...
    // Key and IV values.
    const char *pcCode = "f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8";
    unsigned char acKey[EVP_MAX_KEY_LENGTH + 1];
    unsigned char acIV[EVP_MAX_IV_LENGTH + 1];

    // Load all the encryption ciphers and lookup the one we want to use.
    OpenSSL_add_all_algorithms();
    const EVP_CIPHER *cipher = EVP_get_cipherbyname("aes-256-cbc");
    const EVP_MD *digest = EVP_get_digestbyname("sha1");

    // Generate HashKey for the password.
    int nrounds = 1;
    int nCnt = EVP_BytesToKey(cipher, digest, Global::acDecryptSalt, (const unsigned char *) pcCode, strlen(pcCode), nrounds, acKey, acIV);

...
}

关于aes - 从 C++ 代码和命令行生成相同的 key 和 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15009678/

有关aes - 从 C++ 代码和命令行生成相同的 key 和 IV的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  4. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  5. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  6. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  7. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  8. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  9. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  10. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

随机推荐