I am trying to replicate the encryption logic found in a Java library in a C# application.
The Java contains two methods which I have managed to replicate in C#. I get the same results in each program for any set of data.
createKey(byte data1[], MessageDigest md);
createIV(byte data2[], MessageDigest md);
The logic to generate the key and IV in Java is as follows:
public Cipher getC开发者_如何学Pythonipher(byte[] password) {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte keyData[] = createKey(byte[] password, md);
SecretKey secretKey =
SecretKeyFactory.getInstance("DESede").
generateSecret(new DESedeKeySpec(keyData[]));
IVSpec ivspec = createIV(secretKey.getEncoded(), md);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(1, secretKey, ivSpec, md);
return cipher;
}
Let's say I have the follow:
Java Key HEX: 9c 3a 79 df ba 49 86 0 ed 58 1 d8 9b a7 94 0 bb 3e 8f 80 4d 67 0 0
When I build the secretKey and then call secretKey.getEncoded() I get:
Java Encoded Key: : 9d 3b 79 df ba 49 86 1 ec 58 1 d9 9b a7 94 1 ba 3e 8f 80 4c 67 1 1
Because I don't know what the SecretKey is doing internally I don't know how to replicate this in C#.
My current C# code looks like this:
public static ICryptoTransform createCryptoTransform(String password)
{
ICryptoTransform ct = null;
byte[] keyData = createKey(password);
byte[] ivData = createInitialisationVector(keyData);
printByteArray("keyData", keyData);
printByteArray("ivData", ivData);
TripleDESCryptoServiceProvider tdcsp = new TripleDESCryptoServiceProvider();
tdcsp.Key = keyData; / This seems to be ignored by CreateEncryptor method below
tdcsp.KeySize = 192;
tdcsp.IV = ivData; // This seems to be ignored by CreateEncryptor method below
tdcsp.Mode = CipherMode.CBC;
tdcsp.Padding = PaddingMode.PKCS7; // PKCS5 and PKCS7 provide the same padding scheme
ct = tdcsp.CreateEncryptor(keyData, ivData);
return ct;
}
As you can see, I'm using the ivData[] created from the unencoded key.
Everything works, that is I get the same encrypted result, if I pass the same IV data in when creating the encryptor but unfortunately I cannot modify how it generates it's IVSpec.
What is SecretKey doing internally and how do I replicate this in C#?
DES (and DESede) both derive 56 bits of key material from 64 bit input. The remaining 8 bits are used as parity check bits here. The source code shows you how Java handles this, you can apply the same in C#.
See also the section at the beginning of FIPS 46-3.
精彩评论