解密一个base64字符串iOS

时间:2015-05-19 10:16:03

标签: ios objective-c encryption aes

我正在尝试解密来自服务器的字符串。例如,griDE3DgHKa3PDNir8kJvw ==应解密为“1”

这是从服务端

在Java中生成密钥的方式
private string user;

public UsersLogic(user)
{
    this.user = user;
}

public async Task<Agent> Get()
{
    return await Context.Users.FirstOrDefaultAsync(i => i.ID == user);
}

这是字符串的加密方式

byte[] salt = new byte[]{172, 137, 25, 56, 156, 100, 136, 211, 84, 67,       96, 10, 24, 111, 112, 137, 3};
int iterations = 1024;
var rfc2898 =
new  
System.Security.Cryptography.Rfc2898DeriveBytes("sOme*ShaREd*SecreT", salt, iterations);
byte[] key = rfc2898.GetBytes(16);
String keyB64 = Convert.ToBase64String(key);
System.Console.WriteLine("Key: " + keyB64);

我遇到了这个加密和解密的NSData类别,但我无法清楚地理解所有内容。

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
iv = params.getParameterSpec(IvParameterSpec.class).getIV();
ciphertext = cipher.doFinal(cleartext.getBytes("UTF-8"));
System.out.println("IV:" + Base64.encode(iv));
System.out.println("Cipher text:" + Base64.encode(ciphertext));

}

我们正在使用AES128算法,CBC模式和PKCS5填充。任何人都可以帮助我吗?

我知道这个例子是使用ECB模式和PKCS7填充,但我找不到他们需要的模式来替换。

这是我尝试解码的方式

- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv {
char keyPtr[kCCKeySizeAES128 + 1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

char ivPtr[kCCBlockSizeAES128 + 1];
bzero(ivPtr, sizeof(ivPtr));
if (iv) {
    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
}

NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
                                      kCCAlgorithmAES128,
                                      kCCOptionPKCS7Padding | kCCOptionECBMode,
                                      keyPtr,
                                      kCCBlockSizeAES128,
                                      ivPtr,
                                      [self bytes],
                                      dataLength,
                                      buffer,
                                      bufferSize,
                                      &numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;

2 个答案:

答案 0 :(得分:0)

正如this回答中所解释的,PKCS#5填充只是PKCS#7填充,限制为8字节块大小。此外,从评论到this回答,似乎Java在指定密码为"AES/CBC/PKCS5Padding"时内部使用PKCS#7填充。

source code中的文档到CommonCryptorCBC是默认的阻止模式。

作为结论,你应该没问题

CCCryptorStatus cryptStatus = CCCrypt(operation,
                                      kCCAlgorithmAES128,
                                      kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCBlockSizeAES128,
                                      ivPtr,
                                      [self bytes],
                                      dataLength,
                                      buffer,
                                      bufferSize,
                                      &numBytesEncrypted);

答案 1 :(得分:0)

  1. 您需要将iv与加密数据分开。
  2. 您需要将Base64编码的字符串转换为数据。
  3. 您需要知道密钥是128,192还是256字节并明确设置它。 Java代码可以从提供的密钥长度推断密钥大小。看起来它是byte[] key = rfc2898.GetBytes(16);
  4. 行的128位(16字节)
  5. 删除kCCOptionECBMode选项,正在使用CBC模式,即CBC模式。
  6. 您需要重新编写代码以匹配Java代码,主要是WRT Base64编码。