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!!!