- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试在 CBC 模式下使用 AES-128 加密 320 字节的二进制数据,并将密码存储到一个文件中。输出文件应该是 320 字节,但我得到了 336 字节。这是我的代码:
#include <iostream>
#include <fstream>
#include <crypto++/aes.h>
#include <crypto++/modes.h>
#include <crypto++/base64.h>
#include <crypto++/sha.h>
#include <cryptopp/osrng.h>
#include <crypto++/filters.h>
#include <crypto++/files.h>
namespace CryptoPP
{
using byte = unsigned char;
}
void myAESTest()
{
std::string password = "testPassWord";
// hash the password string
// -------------------------------
CryptoPP::byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE];
CryptoPP::byte passHash[CryptoPP::SHA256::DIGESTSIZE];
CryptoPP::SHA256().CalculateDigest(passHash, (CryptoPP::byte*) password.data(), password.size());
std::memcpy(key, passHash, CryptoPP::AES::DEFAULT_KEYLENGTH);
std::memcpy(iv, passHash+CryptoPP::AES::DEFAULT_KEYLENGTH, CryptoPP::AES::BLOCKSIZE);
// encrypt
// ---------------------------------
int chunkSize = 20*CryptoPP::AES::BLOCKSIZE;
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key, sizeof(key), iv);
std::ofstream testOut("./test.enc", std::ios::binary);
CryptoPP::FileSink outSink(testOut);
CryptoPP::byte message[chunkSize];
CryptoPP::StreamTransformationFilter stfenc(encryptor, new CryptoPP::Redirector(outSink));
for(int i = 0; i < chunkSize; i ++)
{
message[i] = (CryptoPP::byte)i;
}
stfenc.Put(message, chunkSize);
stfenc.MessageEnd();
testOut.close();
// decrypt
// ------------------------------------
// Because of some unknown reason increase chuksize by 1 block
// chunkSize+=16;
CryptoPP::byte cipher[chunkSize], decrypted[chunkSize];
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor;
decryptor.SetKeyWithIV(key, sizeof(key), iv);
std::ifstream inFile("./test.enc", std::ios::binary);
inFile.read((char *)cipher, chunkSize);
CryptoPP::ArraySink decSink(decrypted, chunkSize);
CryptoPP::StreamTransformationFilter stfdec(decryptor, new CryptoPP::Redirector(decSink));
stfdec.Put(cipher, chunkSize);
stfdec.MessageEnd();
inFile.close();
for(int i = 0; i < chunkSize; i++)
{
std::cout << (int)decrypted[i] << ' ';
}
std::cout << std::endl;
}
int main(int argc, char* argv[])
{
myAESTest();
return 0;
}
我无法理解最后 16 个字节是如何生成的。如果我选择忽略解密中的最后 16 个字节,CryptoPP 会抛出 CryptoPP::InvalidCiphertext
错误:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
最佳答案
I'm not able to understand how the last 16 bytes are generated. If I choose to ignore the last 16 bytes in the decryption, Crypto++ throws
InvalidCiphertext
error
最后 16 个字节是填充。填充由 StreamTransformationFilter
过滤器添加;见StreamTransformationFilter Class Reference在手册中。虽然不是很明显,DEFAULT_PADDING
是 PKCS_PADDING
用于 ECB_Mode
和 CBC_Mode
。对于 OFB_Mode
和 CTR_Mode
等其他模式,它是 NO_PADDING
。
您只需为加密和解密过滤器指定NO_PADDING
。但是,您必须确保明文和密文是 block 大小的倍数,对于 AES 是 16。
您可以通过切换到另一种模式(例如 CTR_Mode
)来避开 block 大小限制。但是您必须非常小心 key 或 IV 重用,这可能会因您使用的密码派生方案而变得困难。
所以代替:
CBC_Mode<AES>::Encryption encryptor;
...
StreamTransformationFilter stfenc(encryptor, new Redirector(outSink));
使用:
CBC_Mode<AES>::Encryption encryptor;
...
StreamTransformationFilter stfenc(encryptor, new Redirector(outSink), NO_PADDING);
另见 CBC_Mode在 Crypto++ 维基上。您可能还对 Authenticated Encryption 感兴趣在维基上。
为此,您还可以:
#ifndef CRYPTOPP_NO_GLOBAL_BYTE
namespace CryptoPP
{
using byte = unsigned char;
}
#endif
CRYPTOPP_NO_GLOBAL_BYTE
在 C++17 std::byte
fixes 之后定义.如果未定义 CRYPTOPP_NO_GLOBAL_BYTE
,则 byte
位于全局命名空间中(Crypto++ 5.6.5 及更早版本)。如果定义了 CRYPTOPP_NO_GLOBAL_BYTE
,则 byte
位于 CryptoPP
命名空间(Crypto++ 6.0 及更高版本)中。
为此:
std::ofstream testOut("./test.enc", std::ios::binary);
FileSink outSink(testOut);
您还可以:
FileSink outSink("./test.enc");
为此:
SHA256().CalculateDigest(passHash, (byte*) password.data(), password.size());
std::memcpy(key, passHash, AES::DEFAULT_KEYLENGTH);
std::memcpy(iv, passHash+AES::DEFAULT_KEYLENGTH, AES::BLOCKSIZE);
您可以考虑使用 HKDF
作为推导函数。使用一个密码,但使用两个不同的标签,以确保独立派生。一个标签可能是字符串 "AES key derivation version 1"
,另一个标签可能是 "AES iv derivation version 1"
。
该标签将用作 DeriveKey
的 info
参数。您只需要调用它两次,一次用于 key ,一次用于 iv。
unsigned int DeriveKey (byte *derived, size_t derivedLen,
const byte *secret, size_t secretLen,
const byte *salt, size_t saltLen,
const byte *info, size_t infoLen) const
secret
是密码。如果你有 salt
就使用它。否则 HKDF 使用默认盐。
另见 HKDF在 Crypto++ wiki 上。
最后,关于这个:
You can sidestep the blocksize restriction by switching to another mode like CTR_Mode. But then you have to be very careful of key or IV reuse, which may be difficult due to the password derivation scheme you are using.
您还可以考虑集成加密方案,例如 Elliptic Curve Integrated Encryption Scheme .是IND-CCA2 ,这是一个强大的安全概念。您需要的一切都打包到加密方案中。
在 ECIES 下,每个用户都会获得一个公钥/私钥对。然后,使用一个大的随机 secret 作为 AES key 、iv 和 mac key 的种子。明文经过加密和验证。最后,种子在用户的公钥下加密。密码还是用的,只是用来解密私钥。
关于c++ - AES-128 CBC 模式下加密流末尾的 Crypto++ 额外 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54791882/
我只想使用这 3 种模式从 openSSL 测试 AES: key 长度为 128,192 和 256,但我的解密文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如说 1024
最近我终于(在 stackoverflow 的用户@WhozCraig 的帮助下)开始在 CBC 模式下使用 AES。现在,我想做完全相同的事情,但使用 AES IGE。我查看了 openssl-1.
网络设备已经配置了 snmpv3 用户,使用 AES192 作为隐私协议(protocol)。但是当执行以下命令时 snmpwalk -v3 -l authPriv -u user -a SHA -A
我在 c# 中使用 AES 算法进行加密和解密。我使用 AesCryptoServiceProvider 类进行加密和解密。 这是我在代码中的设置 AesCryptoServiceProvider r
我正在尝试使用具有不同 key 大小的 openssl 的 AES_decrypt 函数来解密密文。我能够成功解密 key 大小 = 128 的消息。这是我的代码 mydecrypt.c #inclu
如何在 AES-128、AES-192 和 AES-256 之间切换。我目前的实现仅使用 AES-128 Cipher cipher = Cipher.getInstance("AES/CBC/NoP
我的问题是我想在一个线图上叠加一个散点图,这两个图的颜色随着一个变量而变化。我只想保留一种颜色的图例。如果我使用 scale_colour_discrete(guide = "none") 它们都将消
我想用 C# 编写一个可以打开 KeePass 的程序1.x kdb 文件。我下载了源代码并尝试移植密码数据库读取功能。数据库内容已加密。加密 key 通过以下方式获得: 用户输入密码; 计算密码的
我只想将ruby代码迁移到Java 这是我的 ruby 代码 require 'openssl' require 'base64' key = '7c54367a45b37a192abc2cd7f45
我正在使用 AES 的 PyCrypto 实现,并且我正在尝试使用 24 字节 key 加密一些文本(24 字节)。 aes_ecb = AES.new('\x00'*24, AES.MODE_ECB
有人比较这些加密算法的优缺点吗? 最佳答案 使用 AES。 更多详细信息: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性而言太短(56 个有效位;这可以被暴力破解,如 m
我在 iOS 中加密一个 NSString,编码和解码都很好: NSString *stringtoEncrypt = @"This string is to be encrypted"; NSStr
我正在尝试使用 nVidia CUDA 在 CTR 模式下实现 AES-256。我已经成功地为 key 扩展编写了 CPU 代码,现在我需要实现实际的 AES-256 算法。根据维基百科,我见过一些代
我正在 Contiki OS 中研究 AES 安全性。我有 AES 库,它支持两种类型的加密/解密: 即时 固定键 在即时中,当我使用 key 加密数据时,会生成新 key 和加密数据。这个新生成的
关于 AES 有很多问题,但我有以下问题。我目前正在使用以下 AES 实现来加密数据 byte [] PRFkey = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
有没有人一起比较这些加密算法的优缺点? 最佳答案 使用 AES。 更多细节: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性来说太短了(56 位有效位;这可以被强制执行,正
我的团队需要开发一种解决方案,以在用 Java 编写的 Android 应用程序的上下文中加密二进制数据(存储为 byte[])。加密后的数据将通过多种方式传输和存储,在此过程中不排除出现数据损坏的情
我在客户端使用 CryptoJS AES 算法加密文本,我在服务器端用 java 解密它,但出现异常。 JS代码: var encrypted = CryptoJS.AES.encrypt("Mess
我之所以问这个问题,是因为 2 天来我已经阅读了很多关于加密 AES 加密的帖子,就在我以为我明白了的时候,我意识到我根本没有明白。 这篇文章是最接近我的问题的,我有完全相同的问题但没有得到解答: C
我想知道 AES 加密后的数据大小,这样我就可以避免缓冲我的 AES 后数据(在磁盘或内存上)主要是为了知道大小。 我使用 128 位 AES 和 javax.crypto.Cipher 和 java
我是一名优秀的程序员,十分优秀!