我正在接收用SJCL加密的数据到一个iOS应用程序中,在那里我需要解密它。另一端使用的是带有AES CCM模式的SJCL,而Apple的CommonCrypto不支持这一模式,因此我使用了VPCCMCrypt库。不可能对发送SJCL密码文本的另一方进行任何更改。
下面是我解密的方法:
+ (NSData *)decryptSjcl:(NSDictionary *)cipher password:(NSString *)password {
if (cipher == nil || password == nil) {
return nil;
}
int version = [cipher[@"v"] intValue];
NSString *iv = cipher[@"iv"];
uint iter = [cipher[@"iter"] unsignedIntValue];
uint ks = [cipher[@"ks"] unsignedIntValue];
uint ts = [cipher[@"ts"] unsignedIntValue];
NSString *mode = cipher[@"mode"];
NSString *adata = cipher[@"adata"];
NSString *algorithm = cipher[@"cipher"];
NSString *salt = cipher[@"salt"];
NSString *ct = cipher[@"ct"];
if (version != 1 || ! [@"aes" isEqualToString:algorithm]) {
return nil;
}
NSData *rawIv = [[NSData alloc] initWithBase64EncodedString:iv options:0];
NSData *rawSalt = [[NSData alloc] initWithBase64EncodedString:salt options:0];
NSData *rawAdata = [[NSData alloc] initWithBase64EncodedString:adata options:0];
NSData *cipherData = [[NSData alloc] initWithBase64EncodedString:ct options:0];
NSData *key;
NSMutableData *decipheredData = nil;
if ([@"ccm" isEqualToString:mode]) {
key = [Cryptor sjclAesKeyForPassword:password salt:rawSalt iterations:iter keySize:ks];
decipheredData = [Cryptor decryptAesCcmData:cipherData iv:rawIv key:key adata:rawAdata tagSize:ts];
}
return decipheredData;
}
SJCL密钥生成:
+ (NSData *)sjclAesKeyForPassword:(NSString *)password salt:(NSData *)salt iterations:(uint)iterations keySize:(uint)keySizeBits {
NSMutableData *derivedKey = [NSMutableData dataWithLength:keySizeBits / 8];
int result = CCKeyDerivationPBKDF(kCCPBKDF2,
password.UTF8String,
[password lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
salt.bytes,
salt.length,
kCCPRFHmacAlgSHA256,
iterations,
derivedKey.mutableBytes,
derivedKey.length);
NSAssert(result == kCCSuccess, @"Unable to create AES key for password: %d", result);
return derivedKey;
}
AES CCM解密:
+ (NSMutableData *)decryptAesCcmData:(NSData *)cipherData iv:(NSData *)iv key:(NSData *)key adata:(NSData *)adata tagSize:(uint)tagSizeBits {
VPCCMCrypt *ccm = [[VPCCMCrypt alloc] initWithKey:key
iv:iv
adata:adata
tagLength:tagSizeBits / 8];
[ccm decryptDataWithData:cipherData
finishedBlock:^(NSData *data) {
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Decrypted SJCL message: %@", result);
}
errorBlock:^(NSError *error) {
NSLog(@"ERROR");
}];
return nil;
}
+ (NSData *)decryptSjcl:(NSDictionary *)cipher password:(NSString *)password {
if (cipher == nil || password == nil) {
return nil;
}
int version = [cipher[@"v"] intValue];
NSString *iv = cipher[@"iv"];
uint iter = [cipher[@"iter"] unsignedIntValue];
uint ks = [cipher[@"ks"] unsignedIntValue];
uint ts = [cipher[@"ts"] unsignedIntValue];
NSString *mode = cipher[@"mode"];
NSString *adata = cipher[@"adata"];
NSString *algorithm = cipher[@"cipher"];
NSString *salt = cipher[@"salt"];
NSString *ct = cipher[@"ct"];
if (version != 1 || ! [@"aes" isEqualToString:algorithm]) {
return nil;
}
NSMutableData *rawIv = [[NSMutableData alloc] initWithBase64EncodedString:iv options:0];
NSMutableData *rawSalt = [[NSMutableData alloc] initWithBase64EncodedString:salt options:0];
NSMutableData *rawAdata = [[NSMutableData alloc] initWithBase64EncodedString:adata options:0];
NSMutableData *cipherData = [[NSMutableData alloc] initWithBase64EncodedString:ct options:0];
NSData *key;
NSData *decipheredData = nil;
if ([@"ccm" isEqualToString:mode]) {
key = [Cryptor sjclAesKeyForPassword:password salt:rawSalt iterations:iter keySize:ks];
// Clamp the SJCL IV - They use a 16 byte IV for CCM mode which is against specification and they do a funky
// clamping. CCM mode IV should be max 13 bytes long. They almost always clamp it to 13 bytes but save the whole
// 16 bytes in their JSON container.
// for (L=2; L<4 && ol >>> 8*L; L++) {}
// if (L < 15 - ivl) { L = 15-ivl; }
// iv = w.clamp(iv,8*(15-L));
int64_t ivl = rawIv.length;
int64_t ol = cipherData.length - (ts / 8);
int64_t L = 2;
for (L = 2; L < 4 && ol >> 8*L; L++) {}
if (L < 15 - ivl) {
L = 15 - ivl;
}
NSRange subrange = NSMakeRange(0, (NSUInteger)(15 - L));
decipheredData = [Cryptor decryptAesCcmData:cipherData iv:[rawIv subdataWithRange:subrange] key:key adata:rawAdata tagSize:ts];
}
else {
decipheredData = nil;
}
return decipheredData;
}
最后一件缺失的事情是验证标记,我无法做到这一点。有什么想法吗?
SJCL没有在AES-CCM模式下使用整个(128/192/256bit)IV,但演示页面显示了它。用更少的字节试试。
您可以在这里找到IV长度计算的工作原理:http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_ccm.js.html
for (L=2; L<4 && ol >>> 8*L; L++) {}
if (L < 15 - ivl) { L = 15-ivl; }
iv = w.clamp(iv,8*(15-L));
执行此操作后,当运行/opt/bin/openssl密码时,列表中看不到aes-128-ccm密码: 但如果运行/opt/bin/openssl enc-help 2>&1,我会看到“-aes-128-ccm”: 我使用命令(在前面提到的文章中给出)重新安装了ruby 2.0.0p0和rvm。然后运行。返回以下错误: 我的问题是如何在Ruby中添加对AES-128-CCM的支持/我在这里做错了什么
问题内容: 我尝试解密最初使用Java中的Objective-C加密的数据。 还有其他问题要提及,但是它们确实很混乱,许多问题还没有解决,因此我将发表自己的问题。 这是加密数据的代码: 我执行此功能,并使用以下代码将结果数据写入光盘: 在Java中,我使用以下代码来尝试实现相同的行为: 如果现在尝试解密通过Objective-C加密的文件,则会收到错误的填充异常。如果我打开两个带有加密内容的文件,
我知道有几个与此相关的问题,但是大多数答案都提供了.NET4.0及以上版本的解决方案。对于我的用途,我必须以.NET3.5为目标。我想简单地加密和解密一个字符串存储在一个文件中,所讨论的文本不是敏感的用户/个人信息。
我试图解密C#加密数据在Java没有成功。我用的是128位密钥 这是java代码: 你知道会出什么问题吗? 谢谢 使现代化 对不起,我太笨了,我忘了写实际的错误消息。这是: 线程“main”javax中出现异常。加密。BadPaddingException:组织中的填充块已损坏。弹跳船舱。jcajce。供应商。对称的。util。基本分组密码。javax上的engineDoFinal(未知源代码)。
我试图用C#加密一些(cookie)数据,然后用PHP解密。我选择使用Rijndael加密。我几乎让它工作,除了只有一部分的文本被解密!我从这个例子开始工作:用C#解密PHP加密的字符串 这是我正在加密的文本(JSON)(删除敏感信息): 所以我登录到 C# 应用程序,该应用程序从存储的密钥和 IV 创建/编码 cookie,然后重定向到应该解密/读取 cookie 的 PHP 应用程序。当我解密
我收到一个错误解密在C#中加密的消息(使用相应的公钥/私钥) 我的客户端是用C编写的,服务器是用Go编写的。我通过go的crypto/rsa包生成了一个私钥和公钥(使用rsa.GenerateKey(随机读取器,bits int))。然后,我将生成的公钥文件存储在客户端可以访问的地方,将私钥存储在服务器可以访问的地方。我使用以下代码(使用bouncy castle)在客户端上加密: go服务器从标