indisoluble / AesGcm

(DEPRECATED - USE: https://developer.apple.com/documentation/cryptokit/aes/gcm) Galois/Counter Mode (GCM) with Advanced Encryption System (AES).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to generate AES/GCM/NOPADDING

galanblancom opened this issue · comments

Hello, how I can generate a ciphered with no padding?

I'm testing with this: 1234567891234567, I'm waiting this base64 result: QlWHK6ZeJptBBCmDLhOpkGAct0ZDO8jaaOFp9sxMSo0=; but the library returns: QlWHK6ZeJptBBCmDLhOpkA==

Thanks in advance.

Hi,

I am not sure what you mean by "no padding"? As far as I can see, there is no padding in AesGcm, however I mention it in this other repository: AesKeyWrap.

Anyway, both cases require more than just the data you want to cipher to actually do the job:

  • AesKeyWrap requires the KeyEncryptionKey
  • AesGcm requires AdditionalAuthenticatedData, AuthenticationTagLength, InitializationVector and Key

Could you copy here the source code you are using or an example with keys you do no mind to share?

Regards.

Hi,

Another case: I'm using this key: Mirel1@Mirel1@1@, testing with this: 1234567891234567.

In Java I'm getting a 32 length encrypted buffer, converted to base64 is 21JNBYm9pY9jIJwowUoZK3LdVFErlT1gk6t_NjX9nV4=, on Objective C the cipheredBuffer has 16, converted to base64 is 21JNBYm9pY9jIJwowUoZKw==.

text variable = 1234567891234567 on both cases

Java code:
String CIPHER_ALGORITHM = "AES/GCM/NOPADDING";
String KEY = "Mirel1@Mirel1@1@";
String KEY_ALGORITHM = "AES";

    Key secretKey = new SecretKeySpec(KEY.getBytes(), KEY_ALGORITHM);

    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    IvParameterSpec ivspec = new IvParameterSpec(KEY.getBytes());
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
    byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8"));
    return Base64.encodeToString(encrypted, Base64.URL_SAFE);

Objective C code:
NSString *key = @"Mirel1@Mirel1@1@";
NSData *keyPtr = [key dataUsingEncoding:NSUTF8StringEncoding];

   IAGCipheredData *cipheredData = [IAGAesGcm cipheredDataByAuthenticatedEncryptingPlainData:text
                                                              withAdditionalAuthenticatedData:keyPtr
                                                                      authenticationTagLength:IAGAuthenticationTagLength128
                                                                         initializationVector:keyPtr
                                                                                          key:keyPtr
                                                                                        error:nil];

   NSMutableData  *buffer = [NSMutableData dataWithBytes:[cipheredData cipheredBuffer] length:[cipheredData cipheredBufferLength]];

    return buffer;

Thank you!!!

Hi again,

I might have found the problem, let's see if I am right :)

First of all, as you know, AesGcm returns a data structure named IAGCipheredData with 2 fields: cipheredBuffer & authenticationTag. However, I think Cipher (in Java) returns both buffers concatenated in a single buffer. I realised this after I read this article: Security Best Practices: Symmetric Encryption with AES in Java and Android

GCM is basically CTR mode which also calculates an authentication tag sequentially during encryption. This authentication tag is then usually appended to the cipher text. Its size is an important security property, so it should be at least 128 bit long.

To prove this, I wrote the following code:

- (void)test {
    // given
    NSData *key = [@"Mirel1@Mirel1@1@" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *iv = key;

    NSData *aad = [NSData data];

    NSData *plainData = [@"1234567891234567" dataUsingEncoding:NSUTF8StringEncoding];

    // when
    IAGCipheredData *cipheredData = [IAGAesGcm cipheredDataByAuthenticatedEncryptingPlainData:plainData
                                                              withAdditionalAuthenticatedData:aad
                                                                      authenticationTagLength:IAGAuthenticationTagLength128
                                                                         initializationVector:iv
                                                                                          key:key
                                                                                        error:nil];

    // then
    NSString *expectedCiphertext = @"21JNBYm9pY9jIJwowUoZK3LdVFErlT1gk6t_NjX9nV4=";
    NSData *cipheredBuffer = [NSData dataWithBytes:cipheredData.cipheredBuffer
                                            length:cipheredData.cipheredBufferLength];
    NSData *extraBuffer = [NSData dataWithBytes:cipheredData.authenticationTag
                                         length:cipheredData.authenticationTagLength];
    NSMutableData *fullBuffer = [[NSMutableData alloc] initWithData:cipheredBuffer];
    [fullBuffer appendData:extraBuffer];

    NSString *ciphertext = [fullBuffer base64EncodedStringWithOptions:0];
    XCTAssertEqualObjects(expectedCiphertext, ciphertext);
}

If you run this code, you will still get an error. ciphertext is equal to 21JNBYm9pY9jIJwowUoZK3LdVFErlT1gk6t/NjX9nV4= while the value you provided in your previous comment was: 21JNBYm9pY9jIJwowUoZK3LdVFErlT1gk6t_NjX9nV4=. But notice that the only difference is that in ciphertext we have a character / while in yours we have a _. However, if we check the Base64 table, we can see that / is a valid character while _ is not.

Also, notice that value provided to withAdditionalAuthenticatedData is an empty NSData instance, not the key.

Not sure why Java gave you a _ instead of a / ¯_(ツ)_/¯

Regards.

BTW, when I wrote this library Apple did not officially support AES GCM but it does now. I recommend you to have a look to: https://developer.apple.com/documentation/cryptokit/aes/gcm . Although I did not try it myself so I am not going to be able to help you with it. Sorry.

Brilliant!, that's all I need, thanks!!!