【问题标题】:AES128 encryption libgcrypt outputs junkAES128 加密 libgcrypt 输出垃圾
【发布时间】:2018-12-12 19:09:07
【问题描述】:

我使用这个已解决的帖子作为参考,但似乎无法得到相同的结果:AES128 in libgcrypt not encrypting

当我将字符串打印到控制台时,我得到了垃圾字符。我认为这可能是由于'\0' 在字符串中,但我不确定该怎么做。

//aes.cpp

#include "aes.h"
#include <iostream>
#include <stdio.h>

#define GCRY_CIPHER GCRY_CIPHER_AES128   // Pick the cipher here
#define GCRY_MODE GCRY_CIPHER_MODE_ECB // Pick the cipher mode here

aes::aes(std::string k)
{
    key_ = k;
    keyLength_ = gcry_cipher_get_algo_keylen(GCRY_CIPHER);

    gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
    gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_MODE, 0);
    gcry_cipher_setkey(handle, key_.c_str(), keyLength_);
}

void aes::encrypt(string text, std::vector<char>& ret) {
    size_t textLength = text.size() + 1;
    ret.resize(textLength);
    gcry_cipher_encrypt(handle, ret.data(), textLength, text.c_str(), textLength);
}

string aes::decrypt(std::vector<char> const& text) {
    size_t textLength = text.size() + 1;


    char * decBuffer = new char[textLength];
    gcry_cipher_decrypt(handle, decBuffer, textLength, text.data(), textLength);
    string ret (decBuffer);
    delete [] decBuffer;
    return ret;
}

//aes.h

#include <gcrypt.h>
#include <iostream>

#ifndef AES_H
#define AES_H

class aes
{
public:
    aes(std::string);
    ~aes();

    gcry_cipher_hd_t handle;
    void encrypt(std::string, std::vector<char>&);
    std::string decrypt(std::vector<char> const&); 

private:
    std::string key_;
    size_t keyLength_; 
};

#endif // AES_H

//main.cpp

#include "aes.h"
#include <iostream>

int main()
{
    std::vector<char> data;

    aes bb = aes("one test AES key");
    bb.encrypt("Some message", data);

    std::string dec = bb.decrypt(data);
    std::cout << "decrypted string " << dec << std::endl;
    return 0;
    //output gives me: decrypted string �

}

【问题讨论】:

  • gcry_cipher_decrypt 不会以某种方式返回解密字符串的长度?
  • @PaulMcKenzie gcry_cipher_decrypt 在成功或错误代码时返回 0
  • Possible duplicate。一旦你知道大小,你构造的字符串应该是string ret(decBuffer, size); 而不仅仅是string ret(decBuffer);
  • 我检查了是否有错误代码要返回。我得到gcry_cipher_decrypt failed: gcrypt/Invalid length
  • GCRY_CIPHERGCRY_MODE 是什么?

标签: c++ aes libgcrypt


【解决方案1】:

对于 ECB 模式下的 AES128,要加密的数据大小必须是 128 位的倍数。明文和密文的大小必须完全相同。

这里的工作代码让您了解需要做什么才能使其工作。但我强烈建议您重新考虑使用 ECB。

#include <gcrypt.h>
#include <iostream>
#include <vector>
#include <stdio.h>

class aes
{
public:
    aes(std::string);
    ~aes() { ; }

    gcry_cipher_hd_t handle;
    void encrypt(std::string, std::vector<char>&);
    std::string decrypt(std::vector<char> const&); 

private:
    std::string key_;
    size_t keyLength_; 
};

#define GCRY_CIPHER GCRY_CIPHER_AES128
#define GCRY_MODE GCRY_CIPHER_MODE_ECB

aes::aes(std::string k)
{
    key_ = k;
    keyLength_ = gcry_cipher_get_algo_keylen(GCRY_CIPHER);

    gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
    gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_MODE, 0);
    gcry_cipher_setkey(handle, key_.c_str(), keyLength_);
}

void aes::encrypt(std::string text, std::vector<char>& ret)
{

    // round up to the nearest multiple of the AES block size
    while ((text.size() & 0xf) != 0xf)
        text += " ";

    size_t textLength = text.size() + 1;
    ret.resize(textLength);
    int err = gcry_cipher_encrypt(handle, ret.data(), textLength, text.c_str(), textLength);
    if (err != 0)
    {
       std::cout << "encrypt fail" <<
           gcry_strsource(err) << " " <<
           gcry_strerror(err) << std::endl;
    }
}

std::string aes::decrypt(std::vector<char> const& text) {
    size_t textLength = text.size();

    char * decBuffer = new char[textLength];

    int err=gcry_cipher_decrypt(handle, decBuffer, textLength, text.data(), textLength);
    if (err != 0)
    {
       std::cout << "decrypt fail: " <<
           gcry_strsource(err) <<  " " <<
           gcry_strerror(err) << std::endl;
     }

    std::string ret (decBuffer);
    delete [] decBuffer;
    return ret;
}

int main()
{
    std::vector<char> data;

    aes bb = aes("one test AES key");
    bb.encrypt("Some message", data);


    std::string dec = bb.decrypt(data);
    std::cout << "decrypted string " << dec << std::endl;
    return 0;
}

解密的字符串一些消息

【讨论】:

  • 我错过了加密和解密的细节。将我的缓冲区大小更改为 16 字节的倍数解决了这个问题。感谢您为我指出这一点。我将看看其他模式,看看是否有其他更适合我的项目。
  • @KS7X ECB 几乎从来都不是正确的选择。它就像一个链表——你首先学习它,但它几乎从来都不是真正使用的正确东西。 (我会因此从链表粉丝那里得到很多愤怒的 cmets,不是吗?)
猜你喜欢
  • 2014-11-29
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
相关资源
最近更新 更多