Golang encryption ciphertext has padding of As in the beginning [closed] - encryption

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm trying to use a custom IV for encryption but it results in a ciphertext with padding of As in the beginning like
AAAAAAAAAAAAAAAAAAAAACbglBtdgH3ajX1jgkOaVAsFYyDxRRI=
I followed the sample implementation at https://gist.github.com/manishtpatel/8222606 with a few changes. The go playground to run and test https://play.golang.org/p/2rS6zBwbnF
My code is at
https://play.golang.org/p/qlx_cU0VPQ
Here is the encrypt function for references as well
func Encrypt(key []byte, text string) string {
// key := []byte(keyText)
plaintext := []byte(text)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := commonIV
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
// convert to base64
return base64.URLEncoding.EncodeToString(ciphertext)
}

See this example for golang aes encryption, if you don't need to use AES CFB specifically you could just swap out your encrypt function and use GCM instead. TL;DR- Copy & paste your crypto code from this link instead of Stack Overflow.
https://github.com/gtank/cryptopasta/blob/master/encrypt.go
If you're just learning watch the associated talk and read the code linked, if you're actually encrypting with this, use the linked code.
Video on Go crypto
Repo with vetted crypto examples
PS I'm no expert but your iv should be random each time shouldn't it? To fix your code above you need to copy the iv/nonce in with something like:
copy(ciphertext[:aes.BlockSize], iv[:])
the idea is the unique random nonce is at the start of ciphertext, and used to decrypt (so commonIV shouldn't exist) this stops it producing the same output for the same cleartext. Note how your code when fixed produces the same output each time - that's bad.
But please, don't use advice from people on stack overflow for crypto, and certainly not from me, see the links here instead, and heed the instructions. This stuff is too hard to work out by trial and error.

Related

Why does EVP_CIPHER is EVP_aes_256_cbc() succeed when key length is not equal 256bits?

The code encrypt/decrypt function with openssl library, like following...
EVP_EncryptInit_ex( ctx, EVP_aes_256_cbc(), NULL, key, iv)
It can work, when the key length is not equal 256 bits(32 bytes).
The key length can be any. Why?
For example, it works fine, and no error received:
char key[]="012345678901234567890";
Why does EVP_CIPHER is EVP_aes_256_cbc() succeed when key length is not equal 256bits?
You seem to be asking why you can encrypt using EVP_aes_256_cbc when the key is smaller, like 128-bits.
If you supply an undersized key you are reading random bytes/garbage at the tail of the key bytes. The function is reading bytes, but you don't know what they are. You may get lucky on the local machine and be able to encrypt and decrypt. It will almost certainly fail to decrypt on a different machine.
Valgrind should alert you to the problem of reading uninaitalezed [key] memory. Asan should alert about a read in a guard zone.
I don't believe EVP_aes_256_cbc pads or expands. Like #Zaph said, always use the correct size. If you need to "stretch" a smaller key into a bigger one, then see HMAC-based Extract-and-Expand Key Derivation Function (HKDF), which extracts entropy then expands it.

MAC variant of MSR DUKPT?

Currently I am working on a ChipCard EMV device decryption. Down below is the related data I have after using the transaction (TLV format as Tag Length Value):
<DFDF54> --- It means KSN
0A
950003000005282005B4
<DFDF59>---- per instruction, it is called Encrypted Data Primative
82 ---- length of value in hex, when more than 255 degits, use 82
00D815F35E7846BF4F34E56D7A42E9D24A59CDDF8C3D565CD3D42A341D4AD84B0B7DBFC02DE72A57770D4F795FAB2CE3A1F253F22E0A8BA8E36FA3EA38EE8C95FEBA3767CDE0D3FBB6741A47BE6734046B8CBFB6044C6EE5F98C9DABCD47BC3FD371F777E7E1DCFA16EE5718FKLIOE51A749C7ECC736CB7780AC39DE062DAACC318219E9AAA26E3C2CE28B82C8D22178DA9CCAE6BBA20AC79AB985FF13611FE80E26C34D27E674C63CAC1933E3F9B1BE319A5D12D16561C334F931A5E619243AF398D9636B0A8DC2ED5C6D1C7C795C00D083C08953BC8679C60
I know BDK for this device is 0123456789ABCDEFFEDCBA9876543210. Per decryption instruction, it mentioned that DFDF59 contains the following tags:
FC<len>/* container for encrypted generic data */
F2<len>/*container for Batch Data*/
... /*Batch Data tags*/
F3<len>/*container for Reversal Data, if any*/
... /*Reversal Data tags*/
Per instruction, it mentioned "MAC variant of MSR DUKPT", where MAC stands for message authentication code, and "Parse the data through TLV format. For encrypted data tag, use TDES_Decrypt_CBC to decrypt it".
I tried to use 3DES DUKPT using KSN, BDK, and encrypted data DFDF59. It wouldn't work. Can anyone in decryption field give me some advice? Our vendor is very reluctant to share their knowledge ...
I have no idea how MAC is really playing a role here in decryption.... I thought MAC is just an integrity check.... I am using session key for 3DES DUKPT that was generated from KSN and BDK. this works for other decryptions in this device, but doesn't solve the DFDF59 (chip card EMV decryption).... That is why I start to wonder whether I am using the right session key or not.... Feel free to just throw ideas out there. Thank you!
If you look closely at DUKPT internals it generates a transaction key out of the current future keys and encryption counter. This 'transaction key' for a specific KSN has several variants (which effectively are just xor masks that you put on the transaction key to differentiate it for PIN, MAC req, MAC rsp, data encryption req and rsp usages). These variants mean that you use a different key to generate PIN and different key to encrypt data (so that you cannot ie. decrypt/attack PINblock when able to select data buffer arbitrarily). Using MAC variant means only that for the encryption operation you will be using a certain mask for the DUKPT transaction key.

Encryption Initialization Vector Failed

I am facing a strange problem, i am using aes encryption with cfb mode. It is going good, I had tested the encryption with fixed IV. But when i use a random IV the problem shows up. I am going in detail.
function Random16DigitsString: AnsiString;
var
i: Integer; c0: byte;
begin
Randomize;
c0:=ord('0');
SetLength(Result, 16);
Result[1] := char(c0+Random(9)+1);
for i:=2 to 16 do Result[i] := char(c0+Random(10));
end;
The sample output of the above code is 8229343736510872
When i use this function in encryption phase its ok, but when i decrypt the file using the same key then the output is garbage. But when i hard code this key in encryption phase then the decryption successfully goes.
What i am missing. I am going with simple random number generator.
I was using AnsiString to store the Key for the Context. This was the real problem because in pascal AnsiString is not single byte. As #CodeInChaos focused on AnsiString, I checked it and found it. So i had replaced the
Key: AnsiString
To
Key : Array [0..32] of Char;
and it successfully worked.
Thank you #CodeInChaos.

TCL code that can encrypt and decrypt a string

I need a piece of code that defines functions which can encrypt and decrypt a piece of string. What I basically want is that the string should not be visible to third-party users, so that when the string originates in one file, it is converted to, say, an integer value using the encrypt function and then it is passed as parameter to another file. There the decrpyt function then decrypts it back and uses the string to perform actions on it.
Any suggestions or already available codes will be just fine!
Please help me out. Thanks!
Install tcllib. There are several standard encryption algorithms implemented in tcllib.
The following encryption algorithms are available:
blowfish: http://tcllib.sourceforge.net/doc/blowfish.html
aes: http://tcllib.sourceforge.net/doc/aes.html
des (including triple des): http://tcllib.sourceforge.net/doc/des.html
rc4: http://tcllib.sourceforge.net/doc/rc4.html
The des package in Tcllib should do what you want. It's pretty easy to use:
package require des
set key "12345678"; # Must be 8 bytes long
set msg "abcde"
##### ENCRYPTION
set encryptedMsg [DES::des -dir encrypt -key $key $msg]
# $encryptedMsg is a bunch of bytes; you'll want to send this around...
##### DECRYPTION
set decryptedMsg [DES::des -dir decrypt -key $key $encryptedMsg]
puts "I got '$decryptedMsg'"
Note that DES will pad the message out to a multiple of 8 bytes long.
Please visit the TCL/TK homepage e.g
here:http://wiki.tcl.tk/900
That's just one way of doing it. There will be much more, I'm sure.

Decrypting DUKPT Encrypted Track Data

As the title says, I am trying to decrypt DUKPT encrypted track data coming from a DUKPT enabled scanner.
I have the ANSI Standard (X9.24) for DUKPT and have successfully implemented the ability to generate the IPEK from the KSN and BDK. Furthermore, I have successfully implemented the ability to generate the Left and Right MAC Request and Response Keys by XORing the PIN Encryption Keys. Lastly, I am able to generate the EPB.
From here, I don't understand how to generate the MAC Request and Response from the L/R Keys that I have generated.
Lastly, once I get to that step, what comes next? When do I actually have the key that decrypts the track data sent by a DUKPT enabled device?
I am aware of the Thales Simulator and jPOS. My code is currently referencing the Thales Simulator to do all of its work. But, the file decryption process just isn't returning the expected data.
If anybody can offer some insight into decrypting track data, it would be much appreciated.
http://thalessim.codeplex.com/
http://jpos.org/
I spent too much time studying the horrible X9.24 spec and finally got both the encryption and decryption working with my vendor’s examples and marketing promptly decided to switch vendors. Since it is a standard, you would think that anybody’s implementation would be the same. I wish. Anyway, there are variations on how things are implemented. You have to study the fine print to make sure you are working things the same as your other side.
But that is not your question.
First if you need to decrypt a data track from a credit card, you are probably interested in producing a key that will decrypt the data based upon the original super secret Base Derivation Key. That has nothing to do with the MAC generation and is only mentioned in passing in that dreadful spec. You need to generate the IPEK for that key serial number and device ID and repeatedly apply the “Non-reversible Key Generation Process” from the spec if bits are set in the counter part of the full key serial number from the HSM.
That part of my code looks like this: (Sorry for the long listing in a posting.)
/*
* Bit "zero" set (this is a 21 bit register)(ANSI counts from the left)
* This will be used to test each bit of the encryption counter
* to decide when to find another key.
*/
testBit=0x00100000;
/*
* We have to "encrypt" the IPEK repeatedly to find the current key
* (See Section A.3). Each time we encrypt (generate a new key),
* we need to use the all prior bits to the left of the current bit.
* The Spec says we will have a maximum of ten bits set at any time
* so we should not have to generate more than ten keys to find the
* current encryption key.
*/
cumBits=0;
/*
* For each of the 21 possible key bits,
* if it is set, we need to OR that bit into the cumulative bit
* variable and set that as the KSN count and "encrypt" again.
* The encryption we are using the goofy ANSI Key Generation
* subroutine from page 50.
*/
for(int ii=0; ii<21; ii++)
{
if( (keyNumber&testBit) != 0)
{
char ksr[10];
char eightByte[8]={0};
cumBits |= testBit;
ksn.count=cumBits; /* all bits processed to date */
memcpy(ksr, &ksn,10); /* copy bit structure to char array*/
memcpy(crypt,&ksr[2],8); /* copy bytes 2 through 9 */
/*
* Generate the new Key overwriting the old.
* This will apply the "Non-reversible Key Generation Process"
* to the lower 64 bits of the KSN.
*/
keyGen(&key, &crypt, &key);
}
testBit>>=1;
}
Where
keyNumber is the current counter from the ksn
ksn is an 80 bit structure that contains the 80 bit Key Serial Number from the HSM
crypt is a 64 bit block of data I have it of type DES_cblock since I am using openSSL.
key is a 128 bit double DES_cblock structure.
The keyGen routine is almost verbatim from the “Non-reversible Key Generation Process” local subroutine on page 50 of the spec.
At the end of this, the key variable will contain the key that can be used for the decryption, almost. The dudes that wrote the spec added some “variant” behavior to the key to keep us on our toes. If the key is to be used for decrypting a data stream such as a credit card track, you will need to XOR bytes 5 and 13 with 0xFF and Triple DES encrypt the key with itself (ECB mode). My code looks like:
DOUBLE_KEY keyCopy;
char *p;
p=(char*)&key;
p[ 5]^=0xff;
p[13]^=0xff;
keyCopy=key;
des3(&keyCopy, (DES_cblock *)&key.left, &key.left);
des3(&keyCopy, (DES_cblock *)&key.right, &key.right);
If you are using this to decrypt a PIN block, you will need to XOR bytes 7 and 15 with 0xFF. (I am not 100% sure this should not be applied for the stream mode as well but my vendor is leaving it out.)
If it is a PIN block, it will be encrypted with 3-DES in ECB mode. If it is a data stream, it will be encrypted in CBC mode with a zero initialization vector.
(Did I mention I don’t much care for the spec?) It is interesting to note that the encryption side could be used in a non-hardware, tamper resistant security module if the server side (above) remembers and rejects keys that have been used previously. The technology is pretty neat. The ANSI spec leaves something to be desired but the technology is all right.
Good luck.
/Bob Bryan
For data encryption, the variant is 0000000000FF0000.0000000000FF0000 so you need to XOR bytes 5 and 13 instead of 7 and 15. In addition, you need an additional 3DES self-encryption step of each key parts (left and right).
Here is the relevant code in jPOS
https://github.com/jpos/jPOS/blob/master/jpos/src/main/java/org/jpos/security/jceadapter/JCESecurityModule.java#L1843-1856

Resources