【问题标题】:Can't get PHP's openssl_encrypt to match output from aes_encrypt in C无法让 PHP 的 openssl_encrypt 与 C 中 aes_encrypt 的输出相匹配
【发布时间】:2013-04-06 02:43:02
【问题描述】:

我不是专业的程序员,所以请多多包涵……

我有一个我正在使用的应用程序,不幸地将密码以明文形式存储在 MySQL 中,这是我不想要的。由于该程序确实使用了 OpenSSL 库,因此我可以访问 aes 函数。

下面我拼凑了使用这些函数加密测试字符串并使用 MD5 对其进行哈希处理的演示代码(因为加密的文本是二进制的):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/md5.h>

char *str2md5(const char *str, int length) {
    int n;
    MD5_CTX c;
    unsigned char digest[16];
    char *out = (char*)malloc(33);

    MD5_Init(&c);

    while (length > 0) {
        if (length > 512) {
            MD5_Update(&c, str, 512);
        } else {
            MD5_Update(&c, str, length);
        }
        length -= 512;
        str += 512;
    }

    MD5_Final(digest, &c);

    for (n = 0; n < 16; ++n) {
        snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
    }

    return out;
}

int main(int argc, char* argv[]) {
        AES_KEY aesKey_;
        unsigned char userKey_[16];
        unsigned char in_[16];
        unsigned char out_[16];

        strcpy(userKey_,"1234567890abcdef");
        strcpy(in_,"texttoencrypt");

        fprintf(stdout,"Original message: %s\n", in_);
        AES_set_encrypt_key(userKey_, 128, &aesKey_);
        AES_encrypt(in_, out_, &aesKey_);

        char *output = str2md5(out_, strlen(out_));
        fprintf(stdout,"MD5 of Encrypted message: %s\n", output);

        AES_set_decrypt_key(userKey_, 128, &aesKey_);
        AES_decrypt(out_, in_,&aesKey_);
        fprintf(stdout,"Recovered Original message: %s\n", in_);
        return 0;
}

这个输出:

Original message: texttoencrypt
MD5 of Encrypted message: 3675b450ae0415e5a8521b9bb7ee01ba
Recovered Original message: texttoencrypt

现在在 PHP 中,我使用此代码生成各种 AES-128 加密字符串,类似地,对结果进行 MD5 处理:

<?php

$methods = openssl_get_cipher_methods();

$plain = "texttoencrypt";
$password = "1234567890abcdef";

foreach ($methods as $method) {

        if (preg_match('/AES-128/', $method)) {
                $encrypted = openssl_encrypt($plain, $method, $password);
                $decrypted = openssl_decrypt($encrypted, $method, $password);
                echo $method . ' : ' . md5($encrypted) . ' ; ' . $decrypted . "\r\n";
        }
}
?>

输出:

AES-128-CBC : 08d6f8e2ae21a7a506fabf91adcc3b63 ; texttoencrypt
AES-128-CFB : ce10ea28d7607bd6514e478e025e47c6 ; texttoencrypt
AES-128-CFB1 : 6adde484b8bee26f9b1ca7856634586d ; texttoencrypt
AES-128-CFB8 : aea100f1473c0a3d6380dd0f28585e19 ; texttoencrypt
AES-128-ECB : 08d6f8e2ae21a7a506fabf91adcc3b63 ; texttoencrypt
AES-128-OFB : ce10ea28d7607bd6514e478e025e47c6 ; texttoencrypt

不幸的是,我没有匹配到 C 代码生成的 3675b450ae0415e5a8521b9bb7ee01ba。我已经尝试了我在 PHP 手册页和 SE 上看到的几乎所有评论,但找不到匹配项。

我不能修改 C 代码,只能修改 PHP...所以任何关于如何让 PHP 匹配 C 输出的指针都非常感谢!

【问题讨论】:

    标签: php c encryption openssl aes


    【解决方案1】:
     AES_encrypt(in_, out_, &aesKey_);
    
     char *output = str2md5(out_, strlen(out_));
    

    谁在处理 null 终止 out 以便 strlen 按预期工作?当然不是AES_encrypt

    此外,在strcpy(userKey_,"1234567890abcdef"); 中,您正在将17 字节的数据(您必须计算空终止符)复制到16char 数组中。

    【讨论】:

    • 抱歉……我只是想或多或少地从应用程序中复制代码。它仅使用基本的 aes_encrypt/decrypt 和密钥设置功能作为 aes.h 中的参考。这对我来说是全新的......我想我已经过头了!
    猜你喜欢
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    相关资源
    最近更新 更多