1
votes

I have a 64 character string. The first 32 characters are represent the IV and the last 32 characters are the encrypted message. Each character represents 4 bits, so I have to interpret the string in pairs to get a single byte.

What I am trying to do is to replicate how counter-mode decryption works. As I understand the process, I should be able to xor my cipher text against the encryption of my IV and this should yield the plain text. (note that my cipher text = 16 bytes = one block, so no padding or incrementing of the IV is necessary here, I believe.)

No matter how I do this, I don't get anything legible to output. I think that my problem is how I am encrypting my IV, but I don't know for sure. I've been attacking this forever, but I'm getting nowhere. Can anyone see what I am doing wrong? Here's the code that I wrote:

def decryptCTR(key, ciphertext):
    IV = ciphertext[:32]
    C0 = ciphertext[32:64]
    #convert into 16 byte strings
    key = array.array('B', key.decode("hex")).tostring()
    IV = array.array('B', IV.decode("hex")).tostring()

    # ENCRYPT iv with the key
    encodeAES = lambda c, s: base64.b64encode(c.encrypt(s))
    cipher = AES.new(key, AES.MODE_CFB)
    encryptedIV = encodeAES(cipher, IV)

    #xor the encrypted iv with the ciphertext block
    print "XOR: " + strXOR(encryptedIV, C0)

    return
1
you could use key = binascii.unhexlify(key). In your code strXOR() receives one argument as a base64 encoded string and another as a hex string. It doesn't seem right. Does it work cypher=AES.new(key16, CFB, iv16); cypher.decrypt(unhexlify(c0))? - jfs
tools.ietf.org/html/rfc3686 rfc 3686 contains a good description of what is necessary and test vectors. - andrew cooke
Thanks to both of you. I didn't even know about the unhexlify command, but it seems to wind up with the same result as my array.array...tostring() operation. I didn't show the function strXOR(), since it is outside of what I am dealing with here, but it works just fine. Still making no progress... - AndroidDev
i suspect this won't help, but since there's no marked correct answer here you may be desperate enough to work through it. the code at github.com/andrewcooke/particl/blob/master/src/cl/parti/… uses aes in ctr mode to generate a stream of random data. however, although it calls java crypto classes, it's written in clojure. one thing i notice checking my code against yours is that you don't need to xor. that's done for you by the encrypt routines. the tests at github.com/andrewcooke/particl/blob/master/test/cl/parti/… check against the rfc above. - andrew cooke

1 Answers

2
votes

The answer is indeed simple: don't encrypt the IV. The IV should be send in the clear.