Crypto++ AES in GCM is producing similar ciphertexts
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++
|
show 2 more comments
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++
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
|
show 2 more comments
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++
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++
c++ cryptography c++17 crypto++
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
|
show 2 more comments
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
|
show 2 more comments
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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