[cifs-protocol] FW: [REG:111061756137964] Encryption of the key for "netsh branchcache importkey and exportkey.

Christopher R. Hertel crh at samba.org
Tue Jul 5 22:46:38 MDT 2011


I was able to decrypt an extracted key.  Here are some quick notes, which 
may be useful to those writing the documentation on key extraction.

- The block size, as you (Edgar) noted, is 16 bytes.  As it turns out,
   this is the *standard* block size for AES CBC.  AES, however, is
   derived directly from Rijndael (the name of the cypher before it won
   the competition to become AES).  Rijndael allows variable block sizes.

   Since some cryptographic toolkits implement the broader Rijndael
   cypher, it is worth mentioning that 16-bytes is the AES standard
   block size.

- The initialization vector (IV) is also 16 bytes, to match the block

   It took us a while to figure out that the IV should be an array of
   16 bytes initialized to all zeros.  The IV is required by the AES CBC

- The padding, as noted, is PKCS7.  There will be 1 to 16 bytes of
   padding, so the last byte of the decrypted data is guaranteed to be
   part of the padding.  See rfc2315, section-10.3.

I was testing using two different implementations of AES:  MCrypt and 
OpenSSL.  MCrypt implements Rijndael and uses the cyphername "rijndael-128" 
to indicate a block size (not key length!) of 128 bits (16 bytes).

In summary, the formula for decryption is as follows:

1) The passphrase is in Unicode UTF-16-LE encoding.
    The decryption key is the SHA256 of the passphrase, EXcluding the
    NUL terminator.  The key is, therefore, exactly 32 bytes (256 bits)
    in length.

    key = SHA256( passphrase )

2) The Initialization Vector (IV) is a string of 16 NUL bytes.

3) The algorithm is AES-256, where 256 represents the size of the key.
    The algorithm mode is CBC, and the block size is 16 bytes (as
    defined in the AES standard).

4) The decrypted output (plaintext) is exactly the same length as the
    input (cyphertext).  However, it is composed of three parts:

            32 bytes: The SHA256 of the actual PeerDist Secret Key.
    len-(32+n) bytes: The actual PeerDist Secret Key.
             n bytes: PKCS7 padding.

    Where n is the numeric value of the last byte of the decrypted
    plaintext and len is the total length of the original cyphertext.

Phew.  :)

I have both my Mcrypt and OpenSSL implementations working now.  I will 
polish them a little and post them somewhere (possibly CIFS.Org).  I also 
want to get this working in Python.

Chris -)-----

On 07/05/2011 02:51 PM, Christopher R. Hertel wrote:
> Thanks, Edgar.
> That's another critical piece of information.  I will keep working with this.
> Chris -)-----
> Edgar Olougouna wrote:
>> Hi Chris,
>> Just a quick follow-up, the block size is 16.
>> Thanks,
>> Edgar

"Implementing CIFS - the Common Internet FileSystem" ISBN: 013047116X
Samba Team -- http://www.samba.org/     -)-----   Christopher R. Hertel
jCIFS Team -- http://jcifs.samba.org/   -)-----   ubiqx development, uninq.
ubiqx Team -- http://www.ubiqx.org/     -)-----   crh at ubiqx.mn.org
OnLineBook -- http://ubiqx.org/cifs/    -)-----   crh at ubiqx.org

More information about the cifs-protocol mailing list