Crypto++ AES in GCM is producing similar ciphertexts












3















I'm trying to implement a barebones, start-to-finish AES encryption that is correct and secure. For my purposes, I just want to generate the ciphertext of the output of some benchmarking programs, to simulate what kind of ciphertext would be written to say, a cloud storage server. After reading about it some, I came to the conclusion that for my purposes, authenticated encryption produced by AES in GCM mode is representative of ciphertexts I would see in use on real servers.



Starting from the example code on the Crypto++ Wiki page, I came up with the following snippet to read in some strings from a file and dump the ciphertext. The problem is that the ciphertexts I am getting out are very similar, the upper half being identical in many of the outputs. I suspect it is due to the way I am using/initializing the AutoSeededRandomPool, but I don't know enough about it to figure out how to fix it. It looks like the underlying code is making calls to the OS (Ubuntu 16.04) to generate entropy, which leads me to believe that perhaps there is not enough time between calls for this value to change.



Thanks in advance for any help you can give.



#include "osrng.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "hex.h"
#include "filters.h"
#include "aes.h"
#include "gcm.h"
#include "secblock.h"

using namespace std;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
using CryptoPP::GCM;
using CryptoPP::SecByteBlock;

// Single randomly seeded RNG
AutoSeededRandomPool rnd;

// Generate a string buffer for the input/output data
string plainText, cipherText, encoded;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

// Generate an initial value vector (public but unique per msg)
SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, iv.size());

for (size_t i = 0; i < numLines; ++i)
{
getline(inputFileStream, plainText);

// Do encryption
GCM<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), iv, iv.size());
StringSource
(
plainText,
true,
new AuthenticatedEncryptionFilter
(
e,
new StringSink(cipherText)
)
);

encoded.clear();
StringSource
(
cipherText,
true,
new HexEncoder
(
new StringSink(encoded)
)
);
cout << "Cipher Text: " << encoded << endl;
}


Here is an example of output ciphertexts:



Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6




Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6D8B9F0691B616C2E996B5E473860EE348C09A1F0FC




Moving the IV generation outside of the loop, there is similar behavior:



Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87




Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87FA3272CFE669E235CE452FCEEA59CC8CA34554FF25




Addendum to the answer below:



In the code I neglected to clear the string "cipherText" at each iteration of the loop. Apparently the StringSink operations were just appending the new cipher texts to the end of the cipherText, which is why they were identical. Thanks for all the help!










share|improve this question

























  • The verbatim code

    – Onofog
    Nov 13 '18 at 21:28






  • 1





    @kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

    – Maarten Bodewes
    Nov 13 '18 at 22:03






  • 1





    Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

    – Maarten Bodewes
    Nov 13 '18 at 22:10








  • 1





    @kelalaka Was programming mistake, ciphertext was appended...

    – Maarten Bodewes
    Nov 13 '18 at 23:10






  • 1





    It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

    – kelalaka
    Nov 14 '18 at 17:57


















3















I'm trying to implement a barebones, start-to-finish AES encryption that is correct and secure. For my purposes, I just want to generate the ciphertext of the output of some benchmarking programs, to simulate what kind of ciphertext would be written to say, a cloud storage server. After reading about it some, I came to the conclusion that for my purposes, authenticated encryption produced by AES in GCM mode is representative of ciphertexts I would see in use on real servers.



Starting from the example code on the Crypto++ Wiki page, I came up with the following snippet to read in some strings from a file and dump the ciphertext. The problem is that the ciphertexts I am getting out are very similar, the upper half being identical in many of the outputs. I suspect it is due to the way I am using/initializing the AutoSeededRandomPool, but I don't know enough about it to figure out how to fix it. It looks like the underlying code is making calls to the OS (Ubuntu 16.04) to generate entropy, which leads me to believe that perhaps there is not enough time between calls for this value to change.



Thanks in advance for any help you can give.



#include "osrng.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "hex.h"
#include "filters.h"
#include "aes.h"
#include "gcm.h"
#include "secblock.h"

using namespace std;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
using CryptoPP::GCM;
using CryptoPP::SecByteBlock;

// Single randomly seeded RNG
AutoSeededRandomPool rnd;

// Generate a string buffer for the input/output data
string plainText, cipherText, encoded;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

// Generate an initial value vector (public but unique per msg)
SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, iv.size());

for (size_t i = 0; i < numLines; ++i)
{
getline(inputFileStream, plainText);

// Do encryption
GCM<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), iv, iv.size());
StringSource
(
plainText,
true,
new AuthenticatedEncryptionFilter
(
e,
new StringSink(cipherText)
)
);

encoded.clear();
StringSource
(
cipherText,
true,
new HexEncoder
(
new StringSink(encoded)
)
);
cout << "Cipher Text: " << encoded << endl;
}


Here is an example of output ciphertexts:



Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6




Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6D8B9F0691B616C2E996B5E473860EE348C09A1F0FC




Moving the IV generation outside of the loop, there is similar behavior:



Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87




Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87FA3272CFE669E235CE452FCEEA59CC8CA34554FF25




Addendum to the answer below:



In the code I neglected to clear the string "cipherText" at each iteration of the loop. Apparently the StringSink operations were just appending the new cipher texts to the end of the cipherText, which is why they were identical. Thanks for all the help!










share|improve this question

























  • The verbatim code

    – Onofog
    Nov 13 '18 at 21:28






  • 1





    @kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

    – Maarten Bodewes
    Nov 13 '18 at 22:03






  • 1





    Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

    – Maarten Bodewes
    Nov 13 '18 at 22:10








  • 1





    @kelalaka Was programming mistake, ciphertext was appended...

    – Maarten Bodewes
    Nov 13 '18 at 23:10






  • 1





    It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

    – kelalaka
    Nov 14 '18 at 17:57
















3












3








3








I'm trying to implement a barebones, start-to-finish AES encryption that is correct and secure. For my purposes, I just want to generate the ciphertext of the output of some benchmarking programs, to simulate what kind of ciphertext would be written to say, a cloud storage server. After reading about it some, I came to the conclusion that for my purposes, authenticated encryption produced by AES in GCM mode is representative of ciphertexts I would see in use on real servers.



Starting from the example code on the Crypto++ Wiki page, I came up with the following snippet to read in some strings from a file and dump the ciphertext. The problem is that the ciphertexts I am getting out are very similar, the upper half being identical in many of the outputs. I suspect it is due to the way I am using/initializing the AutoSeededRandomPool, but I don't know enough about it to figure out how to fix it. It looks like the underlying code is making calls to the OS (Ubuntu 16.04) to generate entropy, which leads me to believe that perhaps there is not enough time between calls for this value to change.



Thanks in advance for any help you can give.



#include "osrng.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "hex.h"
#include "filters.h"
#include "aes.h"
#include "gcm.h"
#include "secblock.h"

using namespace std;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
using CryptoPP::GCM;
using CryptoPP::SecByteBlock;

// Single randomly seeded RNG
AutoSeededRandomPool rnd;

// Generate a string buffer for the input/output data
string plainText, cipherText, encoded;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

// Generate an initial value vector (public but unique per msg)
SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, iv.size());

for (size_t i = 0; i < numLines; ++i)
{
getline(inputFileStream, plainText);

// Do encryption
GCM<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), iv, iv.size());
StringSource
(
plainText,
true,
new AuthenticatedEncryptionFilter
(
e,
new StringSink(cipherText)
)
);

encoded.clear();
StringSource
(
cipherText,
true,
new HexEncoder
(
new StringSink(encoded)
)
);
cout << "Cipher Text: " << encoded << endl;
}


Here is an example of output ciphertexts:



Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6




Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6D8B9F0691B616C2E996B5E473860EE348C09A1F0FC




Moving the IV generation outside of the loop, there is similar behavior:



Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87




Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87FA3272CFE669E235CE452FCEEA59CC8CA34554FF25




Addendum to the answer below:



In the code I neglected to clear the string "cipherText" at each iteration of the loop. Apparently the StringSink operations were just appending the new cipher texts to the end of the cipherText, which is why they were identical. Thanks for all the help!










share|improve this question
















I'm trying to implement a barebones, start-to-finish AES encryption that is correct and secure. For my purposes, I just want to generate the ciphertext of the output of some benchmarking programs, to simulate what kind of ciphertext would be written to say, a cloud storage server. After reading about it some, I came to the conclusion that for my purposes, authenticated encryption produced by AES in GCM mode is representative of ciphertexts I would see in use on real servers.



Starting from the example code on the Crypto++ Wiki page, I came up with the following snippet to read in some strings from a file and dump the ciphertext. The problem is that the ciphertexts I am getting out are very similar, the upper half being identical in many of the outputs. I suspect it is due to the way I am using/initializing the AutoSeededRandomPool, but I don't know enough about it to figure out how to fix it. It looks like the underlying code is making calls to the OS (Ubuntu 16.04) to generate entropy, which leads me to believe that perhaps there is not enough time between calls for this value to change.



Thanks in advance for any help you can give.



#include "osrng.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "hex.h"
#include "filters.h"
#include "aes.h"
#include "gcm.h"
#include "secblock.h"

using namespace std;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
using CryptoPP::GCM;
using CryptoPP::SecByteBlock;

// Single randomly seeded RNG
AutoSeededRandomPool rnd;

// Generate a string buffer for the input/output data
string plainText, cipherText, encoded;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

// Generate an initial value vector (public but unique per msg)
SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, iv.size());

for (size_t i = 0; i < numLines; ++i)
{
getline(inputFileStream, plainText);

// Do encryption
GCM<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), iv, iv.size());
StringSource
(
plainText,
true,
new AuthenticatedEncryptionFilter
(
e,
new StringSink(cipherText)
)
);

encoded.clear();
StringSource
(
cipherText,
true,
new HexEncoder
(
new StringSink(encoded)
)
);
cout << "Cipher Text: " << encoded << endl;
}


Here is an example of output ciphertexts:



Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6




Cipher Text:




9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6D8B9F0691B616C2E996B5E473860EE348C09A1F0FC




Moving the IV generation outside of the loop, there is similar behavior:



Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87




Cipher Text:




25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87FA3272CFE669E235CE452FCEEA59CC8CA34554FF25




Addendum to the answer below:



In the code I neglected to clear the string "cipherText" at each iteration of the loop. Apparently the StringSink operations were just appending the new cipher texts to the end of the cipherText, which is why they were identical. Thanks for all the help!







c++ cryptography c++17 crypto++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 12:50







Onofog

















asked Nov 13 '18 at 21:05









OnofogOnofog

1147




1147













  • The verbatim code

    – Onofog
    Nov 13 '18 at 21:28






  • 1





    @kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

    – Maarten Bodewes
    Nov 13 '18 at 22:03






  • 1





    Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

    – Maarten Bodewes
    Nov 13 '18 at 22:10








  • 1





    @kelalaka Was programming mistake, ciphertext was appended...

    – Maarten Bodewes
    Nov 13 '18 at 23:10






  • 1





    It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

    – kelalaka
    Nov 14 '18 at 17:57





















  • The verbatim code

    – Onofog
    Nov 13 '18 at 21:28






  • 1





    @kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

    – Maarten Bodewes
    Nov 13 '18 at 22:03






  • 1





    Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

    – Maarten Bodewes
    Nov 13 '18 at 22:10








  • 1





    @kelalaka Was programming mistake, ciphertext was appended...

    – Maarten Bodewes
    Nov 13 '18 at 23:10






  • 1





    It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

    – kelalaka
    Nov 14 '18 at 17:57



















The verbatim code

– Onofog
Nov 13 '18 at 21:28





The verbatim code

– Onofog
Nov 13 '18 at 21:28




1




1





@kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

– Maarten Bodewes
Nov 13 '18 at 22:03





@kelalaka What about this one: byte iv[ AES::BLOCKSIZE * 16 ];. Uh, what?

– Maarten Bodewes
Nov 13 '18 at 22:03




1




1





Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

– Maarten Bodewes
Nov 13 '18 at 22:10







Let me answer that for you :) crypto.stackexchange.com/a/41610/1172

– Maarten Bodewes
Nov 13 '18 at 22:10






1




1





@kelalaka Was programming mistake, ciphertext was appended...

– Maarten Bodewes
Nov 13 '18 at 23:10





@kelalaka Was programming mistake, ciphertext was appended...

– Maarten Bodewes
Nov 13 '18 at 23:10




1




1





It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

– kelalaka
Nov 14 '18 at 17:57







It is nice that you have solved. Could you add the headers, so your full code can be base for some people?

– kelalaka
Nov 14 '18 at 17:57














1 Answer
1






active

oldest

votes


















3














You're generating the key and IV outside the for loop. That means that you will use the same key / IV combination for the lines your are encrypting. GCM is basically CTR encryption with an authentication tag. That means that similar bits in the plaintext will result in the exact same value. GCM is only secure as long as the IV never repeats.



Put the IV generation inside the loop and you should be OK. Note that, for GCM, 12 bytes IV is more efficient and possibly more secure than a 16 byte IV. Random IV's are often put in front of the ciphertext (by writing them to the StringSink manually).



In your original code you made two mistakes. You printed out the key instead of the IV, which made you believe your RNG was wrong. Furthermore, you wrote to the ciphertext string variable without clearing it first. This made the StringSink append the next ciphertext (and authentication tag) to the ciphertext string. So you got both the first and the second ciphertext when you printed it out.






share|improve this answer


























  • So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

    – Onofog
    Nov 13 '18 at 22:12











  • IV inside the loop code

    – Onofog
    Nov 13 '18 at 22:24













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289486%2fcrypto-aes-in-gcm-is-producing-similar-ciphertexts%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














You're generating the key and IV outside the for loop. That means that you will use the same key / IV combination for the lines your are encrypting. GCM is basically CTR encryption with an authentication tag. That means that similar bits in the plaintext will result in the exact same value. GCM is only secure as long as the IV never repeats.



Put the IV generation inside the loop and you should be OK. Note that, for GCM, 12 bytes IV is more efficient and possibly more secure than a 16 byte IV. Random IV's are often put in front of the ciphertext (by writing them to the StringSink manually).



In your original code you made two mistakes. You printed out the key instead of the IV, which made you believe your RNG was wrong. Furthermore, you wrote to the ciphertext string variable without clearing it first. This made the StringSink append the next ciphertext (and authentication tag) to the ciphertext string. So you got both the first and the second ciphertext when you printed it out.






share|improve this answer


























  • So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

    – Onofog
    Nov 13 '18 at 22:12











  • IV inside the loop code

    – Onofog
    Nov 13 '18 at 22:24


















3














You're generating the key and IV outside the for loop. That means that you will use the same key / IV combination for the lines your are encrypting. GCM is basically CTR encryption with an authentication tag. That means that similar bits in the plaintext will result in the exact same value. GCM is only secure as long as the IV never repeats.



Put the IV generation inside the loop and you should be OK. Note that, for GCM, 12 bytes IV is more efficient and possibly more secure than a 16 byte IV. Random IV's are often put in front of the ciphertext (by writing them to the StringSink manually).



In your original code you made two mistakes. You printed out the key instead of the IV, which made you believe your RNG was wrong. Furthermore, you wrote to the ciphertext string variable without clearing it first. This made the StringSink append the next ciphertext (and authentication tag) to the ciphertext string. So you got both the first and the second ciphertext when you printed it out.






share|improve this answer


























  • So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

    – Onofog
    Nov 13 '18 at 22:12











  • IV inside the loop code

    – Onofog
    Nov 13 '18 at 22:24
















3












3








3







You're generating the key and IV outside the for loop. That means that you will use the same key / IV combination for the lines your are encrypting. GCM is basically CTR encryption with an authentication tag. That means that similar bits in the plaintext will result in the exact same value. GCM is only secure as long as the IV never repeats.



Put the IV generation inside the loop and you should be OK. Note that, for GCM, 12 bytes IV is more efficient and possibly more secure than a 16 byte IV. Random IV's are often put in front of the ciphertext (by writing them to the StringSink manually).



In your original code you made two mistakes. You printed out the key instead of the IV, which made you believe your RNG was wrong. Furthermore, you wrote to the ciphertext string variable without clearing it first. This made the StringSink append the next ciphertext (and authentication tag) to the ciphertext string. So you got both the first and the second ciphertext when you printed it out.






share|improve this answer















You're generating the key and IV outside the for loop. That means that you will use the same key / IV combination for the lines your are encrypting. GCM is basically CTR encryption with an authentication tag. That means that similar bits in the plaintext will result in the exact same value. GCM is only secure as long as the IV never repeats.



Put the IV generation inside the loop and you should be OK. Note that, for GCM, 12 bytes IV is more efficient and possibly more secure than a 16 byte IV. Random IV's are often put in front of the ciphertext (by writing them to the StringSink manually).



In your original code you made two mistakes. You printed out the key instead of the IV, which made you believe your RNG was wrong. Furthermore, you wrote to the ciphertext string variable without clearing it first. This made the StringSink append the next ciphertext (and authentication tag) to the ciphertext string. So you got both the first and the second ciphertext when you printed it out.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 '18 at 23:08

























answered Nov 13 '18 at 21:53









Maarten BodewesMaarten Bodewes

62k1078172




62k1078172













  • So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

    – Onofog
    Nov 13 '18 at 22:12











  • IV inside the loop code

    – Onofog
    Nov 13 '18 at 22:24





















  • So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

    – Onofog
    Nov 13 '18 at 22:12











  • IV inside the loop code

    – Onofog
    Nov 13 '18 at 22:24



















So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

– Onofog
Nov 13 '18 at 22:12





So just to clarify, in my original code, I had IV in the loop. At the advice of @kelalaka, I moved it outside the loop. In the original scenario, the ciphertexts were also quite similar. Is that due to the iv being the same then?

– Onofog
Nov 13 '18 at 22:12













IV inside the loop code

– Onofog
Nov 13 '18 at 22:24







IV inside the loop code

– Onofog
Nov 13 '18 at 22:24




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289486%2fcrypto-aes-in-gcm-is-producing-similar-ciphertexts%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python