我试图为一些将使用Crypto++库的加密操作创建一个Objective包装类。我有几个问题,
这是我正在使用的代码
- (void)testSerpentEncryptonMechanism
{
byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ];
::memset( key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH );
::memset( iv, 0x10, CryptoPP::Serpent::BLOCKSIZE );
NSString *andThisShalBeEncrypted = @"Serpentine and black...";
NSLog(@"will encrypt %@",andThisShalBeEncrypted);
NSString *encrypted = [self encryptWithSerpentString:andThisShalBeEncrypted withKey:key];
NSLog(@"encrypted:%@",encrypted);
NSString *decrypted = [self decryptWithSerpentString:encrypted withKey:key andIV:iv];
NSLog(@"decrypted: %@",decrypted);
}
- (NSString *)encryptWithSerpentString:(NSString *)plaintext withKey:(byte[])keyArray
{
std::string ptext = [plaintext UTF8String];
std::string ciphertext;
byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ];
::memset( key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH );
::memset( iv, 0x10, CryptoPP::Serpent::BLOCKSIZE );
CryptoPP::Serpent::Encryption serpentEncryptor (key, CryptoPP::Serpent::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcSerpentEncryptor (serpentEncryptor, iv);
CryptoPP::StreamTransformationFilter stfSerpentEncryptor(cbcSerpentEncryptor, new CryptoPP::StringSink (ciphertext));
stfSerpentEncryptor.Put( reinterpret_cast<const unsigned char*>( ptext.c_str() ), ptext.length() + 1);
stfSerpentEncryptor.MessageEnd();
std::string finalCT;
CryptoPP::StringSource base64Encoder (ciphertext, true, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(finalCT)));
return @(finalCT.c_str());
}
- (NSString *)decryptWithSerpentString:(NSString *)ciphertext withKey:(byte[])keyArray andIV:(byte[])initializationVector
{
std::string ctext;
std::string plaintext;
byte key[ CryptoPP::Serpent::MAX_KEYLENGTH ], iv[ CryptoPP::Serpent::BLOCKSIZE ];
// ::memset( key, &keyArray , CryptoPP::Serpent::MAX_KEYLENGTH );
// ::memset( iv, (byte[])initializationVector, CryptoPP::Serpent::BLOCKSIZE );
::memset( key, 0x50 , CryptoPP::Serpent::MAX_KEYLENGTH );
::memset( iv, 0x10, CryptoPP::Serpent::BLOCKSIZE );
// decode from base64
std::string encoded = [ciphertext UTF8String];
CryptoPP::StringSource base64Encoder (encoded, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(ctext)));
CryptoPP::Serpent::Decryption serpentDecryptor (key, CryptoPP::Serpent::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcSerpentDecryptor (serpentDecryptor, iv);
CryptoPP::StreamTransformationFilter stfSerpentDecryptor(cbcSerpentDecryptor, new CryptoPP::StringSink (ctext));// crash
stfSerpentDecryptor.Put( reinterpret_cast<const unsigned char*>( ctext.c_str() ), ctext.length() + 1);
stfSerpentDecryptor.MessageEnd();
return @(ctext.c_str());
}1)如何将密钥/IV作为方法参数传递?请看注释代码,这不起作用..。
2)当我试图脱罪的时候,我会撞车
libc++abi.dylib:终止于完全异常的CryptoPP::InvalidCiphertext: StreamTransformationFilter:密文长度不是块大小的倍数
为什么?我以为解密是自动的,加密会相应地填充明文.我也想在方法中添加一个HMAC ..。这将在加密后添加,并在解密前检查,对吗?
发布于 2013-11-28 18:21:31
要获得填充,您必须自己做,或者拥有一个支持标准填充(如PKCS7 )的API。基加密,流密码除外,是基于块的,在较低的级别必须有完整的块。一些较高级别的API提供填充。
我传递键、iv和数据as NSData *,并以data.bytes的形式访问字节。
对于密码输出数据:
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
// ...
dataOut.mutableBytes,
dataOut.length,
&cryptBytes
// ...
dataOut.length = cryptBytes;我将使我的API调用类似于:
- (NSString *)encryptWithSerpentText:(NSString *)text key:(NSData *)key iv:(NSData *)iv;Mac是好的,但您将如何验证它。最好研究认证的最佳实践。
对于HMAC,只需使用苹果提供的CommonCrypto库即可。CommonCrypto还支持: AES128、DES、3 DES、CAST、RC4和Blowfish,但不支持毒蛇。
最后,在服务器和客户端中,每一步都要获得工作日志,这样就可以找到错误数据失败的步骤。在这种情况下,直接针对C++版本的混合目标-C/C++版本。
https://stackoverflow.com/questions/20271678
复制相似问题