CF DESEDE encrypt() Key Length Issue - encryption

I am trying to encrypt a string using ColdFusion encrypt() with a 3rd party provided key like this:
encrypteded = encrypt('theString', 'FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF', 'DESEDE/CBC/NoPadding', 'BASE64', ToBase64('0'));
I get:
"The key specified is not a valid key for this encryption: Wrong key algorithm, expected DESede."
What do I have to do to this key in terms of encoding/decoding to get it into the right format?

Generally, when using provided keys from other languages, you have to do a little gymnastics on it to get it into Base64.
Try this for the key argument:
ToBase64(BinaryDecode('FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF','hex'))
But, to make this work for me, the input string needed to be a multiple of 8 bytes (because you're specifying NoPadding), and the IV needed to also be a multiple of 8 bytes.
So, this ended up working for me - not sure if you'll be able to decrypt it on the other end, tho, if the IV they're specifying is really what you've got listed there.
encrypteded = encrypt('theStrin', ToBase64(BinaryDecode('FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF','hex')), 'DESEDE/CBC/NoPadding', 'BASE64', ToBase64('0000'));
No IV also worked as well (with different output, obviously):
encrypteded = encrypt('theStrin', ToBase64(BinaryDecode('FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF','hex')), 'DESEDE/CBC/NoPadding', 'BASE64');
If you've been given a Hex IV, then you can use it as such:
encrypteded = encrypt('theStrin', ToBase64(BinaryDecode('FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF','hex')), 'DESEDE/CBC/NoPadding', 'BASE64', BinaryDecode("7fe8585328e9ac7b","hex"));
Hopefully this is enough info to get you on your way!

The only thing that seems off to me is the algorithm value you're using. Maybe try this?
encrypteded = encrypt('theString', 'FD52250E230D1CDFD5C2DF0D57E3E0FEFD52250E230D1CDF', 'DESEDE', 'BASE64', ToBase64('0'));
I don't know if the /CBC/NoPadding settings will be what you want, but I don't think they will be allowed in the algorithm argument.

Related

Erlang crypto:stream_init gives different keys on 32 & 64 bit systems. How to use?

I'm getting different keys when using crypto:stream_init(rc4, String). on 32 bit erlang vs 64 bit erlang.
I need to use crypto:stream_encrypt() on one and crypto:stream_decrypt() on the other. Any way to get this to work?
Thanks
crypto:stream_init() returns a State, not a key, and its binary representation will look different on 32 vs 64 bit architectures.
The encrypt/decrypt operations will still work the same, as they rely on the underlying OpenSSL implementation.
As an example of encryption:
State = crypto:stream_init(rc4, "SecretKey").
{Newstate, Secret} = crypto:stream_encrypt(State, "SecretMessage").
And decryption:
State = crypto:stream_init(rc4, "SecretKey"),
{Newstate, Message} = crypto:stream_decrypt(State, Secret),
Message = "SecretMessage".
i.e. the decrypt operation should return the same SecretMessage that was encrypted using the key SecretKey.

python3 imaplib search function encoding

Can someone point me out how to properly search using imaplib in python. The email server is Microsoft Exchange - seems to have problems but I would want a solution from the python/imaplib side.
https://github.com/barbushin/php-imap/issues/128
I so far use:
import imaplib
M = imaplib.IMAP4_SSL(host_name, port_name)
M.login(u, p)
M.select()
s_str = 'hello'
M.search(s_str)
And I get the following error:
>>> M.search(s_str)
('NO', [b'[BADCHARSET (US-ASCII)] The specified charset is not supported.'])
search takes two or more parameters, an encoding, and the search specifications. You can pass None as the encoding, to not specify one. hello is not a valid charset.
You also need to specify what you are searching: IMAP has a complex search language detailed in RFC3501ยง6.4.4; and imaplib does not provide a high level interface for it.
So, with both of those in mind, you need to do something like:
search(None, 'BODY', '"HELLO"')
or
search(None, 'FROM', '"HELLO"')

Setting the text factory for SQLite in Twisted

I am trying to store binary data in a sqlite database using the Twisted adbapi. However, when I run a query to store the data, I get an error:
sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.
After googling a bit, I found the answer for a normal sqlite connection:
con = sqlite3.connect(...)
con.text_factory = str
However, I can't find an equivalent setting to use with a twisted adbapi sqlite connection:
dbpool = adbapi.ConnectionPool("sqlite3", "data.db", check_same_thread=False)
I would appreciate any help!
I figured it out. In order to make changes to the connection after it opens, you have to use the cp_openfun parameter for the ConnectionPool. The following code worked:
def set_text_factory(conn):
conn.text_factory = str
dbpool = adbapi.ConnectionPool("sqlite3", "data.db", check_same_thread=False,
cp_openfun=set_text_factory)

Getting mac from HMAC value and key

I am looking at this page on how to validate HMAC implementation on a platform: http://csrc.nist.gov/groups/STM/cavp/
Test Vectors:
HMAC Test Vectors - These files provide an electronic version of the test vectors
that can be used to informally verify the correctness of an HMAC algorithm
implementation using the HMACVS. However, use of these vectors does not
take the place of validation obtained through the Cryptographic Algorithm
Validation Program (CAVP).
So I open up the file and view the test values:
http://pastebin.com/phJ4C0Fx
it is thousands of lines long but this is the start.
I focus on the first values:
[L=20]
Count = 0
Klen = 10
Tlen = 10
Key = 82f3b69a1bff4de15c33
Msg = fcd6d98bef45ed6850806e96f255fa0c8114b72873abe8f43c10bea7c1df706f10458e6d4e1c9201f057b8492fa10fe4b541d0fc9d41ef839acff1bc76e3fdfebf2235b5bd0347a9a6303e83152f9f8db941b1b94a8a1ce5c273b55dc94d99a171377969234134e7dad1ab4c8e46d18df4dc016764cf95a11ac4b491a2646be1
Mac = 1ba0e66cf72efc349207
My understanding is that with a key and value that openssl would get the mac, however I am not getting the same mac as that above?
echo -n "<Msg here>" | openssl sha1 -hmac "82f3b69a1bff4de15c33"
(stdin)= 981c64f70b07634e01b3800447e6431dddb42530
Any ideas on what I am doing wrong? i am also just guessing sha1, other values don't match either, I don't know how to take from the file what way I should be doing this. The various lengths, and the count. How do I use this information?

Is my PyCrypto implementation secure for my purposes?

I'm not experienced with programming, and the PyCrypto documentation is pretty sparse for a beginner. Let's say that I encrypt a file with the code I have written below, and send it over the internet. What I'm concerned about is the security of the file between computers A and B. Let's assume that the computers themselves are secure and the key is transported securely. Have I implemented things correctly? Anything else I should know about? Using Python 2.7 and PyCrypto 2.6
Thank you in advance for any answer.
from Crypto.Cipher import AES
from Crypto import Random
def get_random(length):
r = Random.new().read(length)
return r
def aes_encrypt(key, file_in, file_out):
data_source = open(file_in, 'rb')
data = data_source.read()
data_source.close()
iv = get_random(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
data_encrypted = iv+cipher.encrypt(data)
file_encrypted = open(file_out, 'wb')
file_encrypted.write(data_encrypted)
file_encrypted.close()
def aes_decrypt(key, file_in, file_out):
data_source = open(file_in, 'rb')
data = data_source.read()
data_source.close()
iv = data[:AES.block_size]
data = data[AES.block_size:]
cipher = AES.new(key, AES.MODE_CFB, iv)
data_decrypted = cipher.decrypt(data)
file_decrypted = open(file_out, 'wb')
file_decrypted.write(data_decrypted)
file_decrypted.close()
#testing
key = get_random(32)
#encrypting the file on computer A
aes_encrypt(key, 'file.dat', 'file.enc')
#decrypting the file on computer B
aes_decrypt(key, 'file.enc', 'file.dat')
You are missing one of the most important considerations in implementing crypto, which is message integrity. Unfortunately just encrypting a message isn't enough to ensure it isn't tampered with, especially in the case of streaming modes like CTR, CFB, and OFB.
It looks like you are using CFB mode (MODE_CFB). The way this works is a random keystream is generated with AES, and the result is XOR-ed against the plaintext. This means that if someone flips a bit in the ciphertext, the corresponding bit will flip in the decrypted plaintext. An attacker could alter your message to mean something entirely different, and there'd be no way for you to detect it. For reference of how CFB mode (decryption) works:
If I flip the first bit of the first block of the ciphertext, it'll flip the first bit of the first block of the decrypted plaintext.
You need to either apply an HMAC or use AES-GCM mode, which will handle confidentiality and integrity together.
There are better mode choices than CFB, so if there's no strong reason for preferring it, I would recommend AES-GCM first, then AES-CTR with HMAC second.

Resources