iOS加密AES128 / CBC / nopadding为什么不工作? [英] iOS encryption AES128/CBC/nopadding why is not working?

查看:147
本文介绍了iOS加密AES128 / CBC / nopadding为什么不工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序需要使用AES / CBC /无填充编码一些数据。该应用程序也在Android上移植。编码完成如下:

  byte [] encodedKey = getKey(); 
SecretKeySpec skeySpec = new SecretKeySpec(encodedKey,AES);
AlgorithmParameterSpec paramSpec = new IvParameterSpec(initializationVector);

密码密码= Cipher.getInstance(AES / CBC / NoPadding);
cipher.init(Cipher.ENCRYPT_MODE,skeySpec,paramSpec);

int blockSize = cipher.getBlockSize();
int diffSize = decryptpted.length%blockSize;
System.out.println(Cipher size:+ blockSize);
System.out.println(当前大小:+ decryptpted.length);
if(diffSize!= 0){
diffSize = blockSize - diffSize;
byte [] oldDecrypted =解密;
decryptpted = new byte [decryptpted.length + diffSize];
System.arraycopy(oldDecrypted,0,decryptpted,0,oldDecrypted.length); (int i = 0; i< diffSize; i ++){
decrypted [i + oldDecrypted.length] =.getBytes()[0];

}
System.out.println(New size:+ decryptpted.length);

}
返回cipher.doFinal(解密);

初始化视图如下所示:

  private byte [] initialVector = new byte [] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00};在iOS上有


$ b $ (NSData *)AES128EncryptWithKey:(NSString *)键
{
//'key'应为AES128的16个字节,将为null-填充否则
char keyPtr [kCCKeySizeAES128 + 1]; //用于终结器的空间(未使用)
bzero(keyPtr,sizeof(keyPtr)); //填充零(用于填充)


//获取密钥数据
[key getCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

//查看文档:对于块密码,输出大小始终小于或等于输入大小加上一个块的大小。
//这就是为什么我们需要在这里添加一个块的大小
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
0x0000,
keyPtr,
kCCKeySizeAES128,
NULL / *初始化向量(可选)* /
[self bytes],dataLength,/ * input * /
buffer,bufferSize,/ * output * /
& numBytesEncrypted);
if(cryptStatus == kCCSuccess){
//返回的NSData获取缓冲区的所有权,并在释放后释放它
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer); //释放缓冲区;
return nil;
}

上述方法是NSData类别的一部分。
该方法被调用如下:

  NSData * data = [@4915200456727dataUsingEncoding:NSUTF8StringEncoding]; 
NSData * cipher = [data AES128EncryptWithKey:@@ x#zddXekZerBBw6];
NSString * ecriptedString = [NSString stringWithFormat:@%。* s,[cipher length],[cipher bytes]];

我的问题是我在iOS和Android上没有收到相同的加密数据。在iOS上,加密数据的长度为0字节。



可以给出任何关于如何使用AES128和CBC加密字符串的指针,也可以是一个例子?



谢谢

解决方案

我找到了解决问题的办法。为了使加密工作没有填充,我不得不添加0x0000而不是kCCOptionPKCS7Padding或kCCOptionECBMode被处理。



另外,如果需要编码的数据不具有kCCKeySizeAES128(16)的长度倍数,那么保存数据的向量必须被调整为具有kCCKeySizeAES128的长度倍数,并且填充一些空值。我添加了空格。

   - (NSData *)AES128EncryptWithKey :( NSString *)键
{
char keyPtr [kCCKeySizeAES128 + 1];
bzero(keyPtr,sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];

int dataLength = [self length];
int diff = kCCKeySizeAES128 - (dataLength%kCCKeySizeAES128);
int newSize = 0;

if(diff> 0)
{
newSize = dataLength + diff;
}

char dataPtr [newSize];
memcpy(dataPtr,[self bytes],[self length]); (int i = 0; i< diff; i ++)
{
dataPtr [i + dataLength] = 0x20;

}

size_t bufferSize = newSize + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
0x0000,//无填充
keyPtr,
kCCKeySizeAES128,
NULL,
dataPtr ,
sizeof(dataPtr),
buffer,
bufferSize,
& numBytesEncrypted);

if(cryptStatus == kCCSuccess)
{
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

return nil;
}


I have an app that needs to encode some data using AES/CBC/no padding. The app is ported also on android. There the encoding is done like this:

byte[] encodedKey = getKey();
    SecretKeySpec skeySpec = new SecretKeySpec(encodedKey, "AES");
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(initializationVector);

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, paramSpec);

    int blockSize = cipher.getBlockSize();
    int diffSize = decrypted.length % blockSize;
    System.out.println("Cipher size: " + blockSize);
    System.out.println("Current size: " + decrypted.length);
    if (diffSize != 0) {
      diffSize = blockSize - diffSize;
      byte[] oldDecrypted = decrypted;
      decrypted = new byte[decrypted.length + diffSize];
      System.arraycopy(oldDecrypted, 0, decrypted, 0, oldDecrypted.length);
      for (int i = 0; i < diffSize; i++) {
        decrypted[i + oldDecrypted.length] = " ".getBytes()[0];
      }
      System.out.println("New size: " + decrypted.length);

    }
    return cipher.doFinal(decrypted);

the initializationVector looks like this:

private byte[] initializationVector = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

on iOS i have something like this for encryption:

- (NSData *)AES128EncryptWithKey:(NSString *)key 
{
    // 'key' should be 16 bytes for AES128, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)


    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 
                                          kCCAlgorithmAES128, 
                                          0x0000,
                                          keyPtr, 
                                          kCCKeySizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

the method described above is part of a category over NSData. the method is called like this:

NSData *data = [@"4915200456727" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *cipher  = [data AES128EncryptWithKey:@"@x#zddXekZerBBw6"];
    NSString *ecriptedString = [NSString stringWithFormat:@"%.*s", [cipher length], [cipher bytes]];

the problem that i have is that i don't receive the same encrypted data on iOS and android. On iOS the encrypted data has 0 bytes in length.

Could you give any pointers on how to encrypt a string using AES128 with CBC and no padding and perhaps an example?

Thank you

解决方案

I found the solution to my problem. In order to make the encryption work without padding i had to add 0x0000 instead of kCCOptionPKCS7Padding or kCCOptionECBMode which are treated.

Also if the data that needs to be encoded doesn't have a length multiple of kCCKeySizeAES128 ( 16 ) then the vector that holds the data must be resized to have the length multiple with kCCKeySizeAES128 and the empty values filled with something. I added spaces.

    - (NSData *)AES128EncryptWithKey:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    int dataLength = [self length];
    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    int newSize = 0;

    if(diff > 0)
    {
        newSize = dataLength + diff;
    }

    char dataPtr[newSize];
    memcpy(dataPtr, [self bytes], [self length]);
    for(int i = 0; i < diff; i++)
    {
        dataPtr[i + dataLength] = 0x20;
    }

    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x0000, //No padding
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          NULL,
                                          dataPtr,
                                          sizeof(dataPtr),
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);

    if(cryptStatus == kCCSuccess)
    {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    return nil;
}

这篇关于iOS加密AES128 / CBC / nopadding为什么不工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆