简体   繁体   中英

AES decryption not working on iOS working on Android used FBEncryptior Library

I am doing AES Decryption with c# in that decrypted data has showing some garbage data at last few characters after decryption.

I am using below code for decryption

+ (NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
   NSData* result = nil;

// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];

// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
NSLog(@"CIV2 : %s",cIv);

if (iv) {
    [iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}

// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);

// do decrypt
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                      FBENCRYPT_ALGORITHM,  //kCCAlgorithmAES128
                                      kCCOptionPKCS7Padding,
                                      cKey,                    //16
                                      FBENCRYPT_KEY_SIZE,   //16
                                      cKey,
                                      [data bytes],
                                      [data length],
                                      buffer,
                                      bufferSize,
                                      &decryptedSize);

if (cryptStatus == kCCSuccess) {

    result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
    free(buffer);
    NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
}

return result;

}

if you see in result in debug it will shows last some characters ate garbage but decrypt complete data.

NSData* data = [self decryptData:encryptedData
                             key:[keyString dataUsingEncoding:NSUTF8StringEncoding]
                              iv:nil];

if (data) {
    return [[NSString alloc] initWithData:data
                                  encoding:NSUTF8StringEncoding];

}

The data is returning nil value.

the C# code is below.

public RijndaelManaged GetRijndaelManaged(String secretKey)
{
    var keyBytes = new byte[16];
    var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
    Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
    return new RijndaelManaged
    {
        Mode = CipherMode.CBC,
        Padding = PaddingMode.PKCS7,
        KeySize = 128,
        BlockSize = 128,
        Key = keyBytes,
        IV = keyBytes
    };
}

public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
    return rijndaelManaged.CreateEncryptor()
        .TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}

public byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
    return rijndaelManaged.CreateDecryptor()
        .TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}

/// <summary>
/// Encrypts plaintext using AES 128bit key and a Chain Block Cipher and returns a base64 encoded string
/// </summary>
/// <param name="plainText">Plain text to encrypt</param>
/// <param name="key">Secret key</param>
/// <returns>Base64 encoded string</returns>
public String Encrypt(String plainText, String key)
{
    var plainBytes = Encoding.UTF8.GetBytes(plainText);
    return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(key)));
}

/// <summary>
/// Decrypts a base64 encoded string using the given key (AES 128bit key and a Chain Block Cipher)
/// </summary>
/// <param name="encryptedText">Base64 Encoded String</param>
/// <param name="key">Secret Key</param>
/// <returns>Decrypted String</returns>
public String Decrypt(String encryptedText, String key)
{
    var encryptedBytes = Convert.FromBase64String(encryptedText);
    return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(key)));
}

Received data From C# : 0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK

Key uses for encryption : e64f9fa01f0418

Decrypted data from iOS : {"Successeed" : "abcdefghijklmnopqrstuvwx!...``~

Expected Decrypted data : {"Successeed" : "abcdefghijklmnopqrstuvwxyz"}

The encrypted data contained hex 227d .

The data hex representation:
7b22537563636565646564223a226162636465666768696a6b6c6d6e6f707172737475767778797a 227d

The string representation:
{"Succeeded":"abcdefghijklmnopqrstuvwxyz"}

Note:
It is best to use a full length key, for AES 16, 24 or 32 bytes, your key is 14 bytes and some undefined method will be used to extend it. Additionally the IV must be lock size, 16-bytes for AES. You are just lucky the padding seems to be the same (0x00) between implementations, don't rely on luck.

Test code:

// Explicit null pad the key and IV to correct lengths
NSData *ivData  = [@"e64f9fa01f0418\x00\x00" dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [@"e64f9fa01f0418\x00\x00" dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncryptedString = @"0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK";
NSData *encryptedData = [[NSData alloc] initWithBase64EncodedString:base64EncryptedString options:0];

NSMutableData *plainData = [NSMutableData dataWithLength: encryptedData.length];
size_t movedBytes = 0;

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(kCCDecrypt,
                   kCCAlgorithmAES128,
                   kCCOptionPKCS7Padding,
                   keyData.bytes, kCCKeySizeAES128,
                   ivData.bytes,
                   encryptedData.bytes, encryptedData.length,
                   plainData.mutableBytes, plainData.length,
                   &movedBytes);

plainData.length = movedBytes;
NSLog(@"Data: %@",plainData);
NSString *decryptedString = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
NSLog(@"String: %@",decryptedString);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM