implementing AES256 encryption into IOS

前端 未结 2 1622
北恋
北恋 2021-02-06 17:34

This is my java code. Now I want to implement same functionality in Objective-C.

Cipher encryptCipher;
IvParameterSpec i         


        
相关标签:
2条回答
  • 2021-02-06 18:10

    Well, how big is your key? kCCAlgorithmAES128 and kCCKeySizeAES256 assume different key sizes. I'm assuming that you're using a 16 byte key, because your Java code would throw an exception otherwise. If you're using a 128 bit key, then you should use kCCKeySizeAES128.

    Additionally, you're not passing in any IV, so it will be assumed that the IV is filled with 0x00 bytes, but in Java, you're using the key as IV.

    Don't use the key as IV. That diminishes the use of the IV in the first place that is there to randomize the ciphertext. You need to generate a random IV for each encryption and send it along with the ciphertext, for example by prepending it to the ciphertext.

    Yes, PKCS#5 padding and PKCS#7 padding are the same thing.

    0 讨论(0)
  • 2021-02-06 18:24

    One problem is that the Java code used CBC mode, the iOS code used ECB mode.

    Next, from the referenced project:
    //result= yHbhApwTpQ2ZhE97AKF/g==
    is invalid Base64, it does not contain a multiple of 4 bytes.

    With these options: CBC, PKCS#7 padding

    inputs:  
       data in: "hello" which will be null padded to the block length of 16-bytes  
       key:  
          base64: VQQhu+dUdqXGoE7RZL2JWg==  
          hex: 550421bbe75476a5c6a04ed164bd895a  
       iv:   
          base64: VQQhu+dUdqXGoE7RZL2JWg==  
          hex: 550421bbe75476a5c6a04ed164bd895a  
    encrypted output:  
       hex: ff21db840a704e943666113dec0285fe  
       base64: /yHbhApwTpQ2ZhE97AKF/g==  
    

    This is the test code:

    NSString *base64Key  = @"VQQhu+dUdqXGoE7RZL2JWg==";
    NSString *dataString = @"hello";
    
    NSData *key  = [[NSData alloc] initWithBase64EncodedString:base64Key  options:0];
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    
    NSLog(@"key:  %@", key);
    NSLog(@"data: %@", data);
    
    NSData *encryptedData = [TestClass crypt:data
                                     iv:key
                                    key:key
                                context:kCCEncrypt];
    
    NSLog(@"encryptedData: %@", encryptedData);
    NSString *encryptedBase64Data = [encryptedData base64EncodedStringWithOptions:0];
    NSLog(@"encryptedBase64Data: %@", encryptedBase64Data);
    

    This is the encryption method (in the class TestClass):

    + (NSData *)crypt:(NSData *)dataIn
                      iv:(NSData *)iv
                     key:(NSData *)symmetricKey
                 context:(CCOperation)encryptOrDecrypt
    {
        CCCryptorStatus ccStatus   = kCCSuccess;
        size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
        NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
    
        ccStatus = CCCrypt( encryptOrDecrypt,
                           kCCAlgorithmAES128,
                           kCCOptionPKCS7Padding,
                           symmetricKey.bytes,
                           kCCKeySizeAES128,
                           iv.bytes,
                           dataIn.bytes,
                           dataIn.length,
                           dataOut.mutableBytes,
                           dataOut.length,
                           &cryptBytes);
    
        if (ccStatus != kCCSuccess) {
            NSLog(@"CCCrypt status: %d", ccStatus);
        }
    
        dataOut.length = cryptBytes;
    
        return dataOut;
    }
    

    Note: I keep separate the encryption and data conversions. Conflating them just makes testing more complicated.

    If you use an on-line encryption implementation the padding will probably not be PKCS#7 because mcrypt does not support it, instead it does non-standard null padding. Since the pad bytes are just the count of pad bytes the padding can be simulated in the input. Here is an example using AES – Symmetric Ciphers Online

    Note that "hello" PKCS#7 padded to a block size of 16 bytes adds 11 bytes of the uint8 value 11 or 0x0B: 68656c6c6f0B0B0B0B0B0B0B0B0B0B0B.

    Finally the question remains why the Java code does not produce this result?

    0 讨论(0)
提交回复
热议问题