2015-06-20 89 views
0

我在C#中有這個代碼,我需要將它遷移到Java。 我需要使用3DES加密。這是強制性的。3DES從C#加密到JAVA

C#

public void test() 
{ 
    string sKSN = "ffff1234560006800010"; 
    string sBDK = "E08A46B616230152230DB9C8DF94C75E"; 
    byte[] dikKSN = new byte[10]; 
    byte[] KSN8 = new byte[8]; 
    byte[] BDK = new byte[16]; 
    byte[] lKey = new byte[8]; 
    byte[] rKey = new byte[8]; 
    string retKey = string.Empty; 
    string lgTxt = string.Empty; 
    dikKSN = this.FromHex(sKSN); // convert hex to byte array 
    BDK = this.FromHex(sBDK); // convert hex to byte array 
    KSN8 = this.CopyByte8(dikKSN); //use the first 8 values 
    lKey = this.TDESEncrypt(KSN8, BDK); 
} 
private byte[] TDESEncrypt(byte[] data, byte[] key) 
{ 
    byte[] retVal = null; 
    byte[] IV = new byte[16]; 
    System.IO.MemoryStream ms = null; 
    System.Security.Cryptography.TripleDES tDES = System.Security.Cryptography.TripleDES.Create(); 
    tDES.BlockSize = 64; 
    tDES.KeySize = 128; 
    tDES.Padding = System.Security.Cryptography.PaddingMode.None; 
    tDES.Mode = System.Security.Cryptography.CipherMode.ECB; 
    System.Security.Cryptography.CryptoStream csEncrypt = null; 
    try 
    { 
     ms = new System.IO.MemoryStream(data); 
     csEncrypt = new System.Security.Cryptography.CryptoStream(ms, tDES.CreateEncryptor(key, IV), System.Security.Cryptography.CryptoStreamMode.Write); 
     retVal = new byte[data.Length]; 
     csEncrypt.Write(data, 0, data.Length); 
     retVal = ms.ToArray(); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
    finally 
    { 
     ms.Close(); 
    } 
    return retVal; 
} 

JAVA

public void test() { 
    String sKSN = "ffff1234560006800010"; 
    String sBDK = "E08A46B616230152230DB9C8DF94C75E"; 
    byte[] dikKSN = new byte[10]; 
    byte[] KSN8 = new byte[8]; 
    byte[] BDK = new byte[16]; 
    byte[] lKey = new byte[8]; 
    byte[] rKey = new byte[8]; 
    String retKey = ""; 
    String lgTxt = ""; 
    dikKSN = this.fromHex(sKSN); // convert hex to byte array 
    BDK = this.fromHex(sBDK); // convert hex to byte array 
    KSN8 = this.copyByte8(dikKSN); //use the first 8 values 
    lKey = this.tDESEncrypt(KSN8, BDK); 
} 
private byte[] tDESEncrypt(byte[] plainTextBytes, byte[] kb) { 
    byte[] cipherText = null; 
    try { 
    final MessageDigest md = MessageDigest.getInstance("md5"); 
    final byte[] digestOfPassword = md.digest(kb); 
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); 
    for (int j = 0, k = 16; j < 8;) { 
     keyBytes[k++] = keyBytes[j++]; 
    } 
    final SecretKey key = new SecretKeySpec(keyBytes, "DESede"); 
    final Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding"); 
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]); 
    cipher.init(Cipher.ENCRYPT_MODE, key, iv); 
    cipherText = cipher.doFinal(plainTextBytes); 
    } catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
    return cipherText; 
} 

測試當我執行desEncrypt方法:

C#

data = {255, 255, 18, 52, 86, 0, 6, 128}; 
key = {224, 138, 70, 182, 22, 35, 1, 82, 35, 13, 185, 200, 223, 148, 199, 94}; 

JAVA

plainBytes = {-1, -1, 18, 52, 86, 0, 6, -128}; 
kb = {-32, -118, 70, -74, 22, 35, 1, 82, 35, 13, -71, -56, -33, -108, -57, 94} 

我認爲我的主要問題是在Java中,一個字節是-128和127字節的原始可以包含255個號碼之間和C#。 數據和關鍵變量的值是從相同的十六進制字符串到字節的轉換中獲得的。

我需要Java代碼返回與C#代碼相同的值。 在這一刻,下面的值是回報:

Java = {99, -104, 95, 92, 59, -75, -30, -16}; 
C# = {171, 58, 144, 248, 46, 146, 227, 224}; 

我沒有兩個結果之間的任何公共價值。

+1

這可以幫助你:http://stackoverflow.com/questions/4266756/can-we-make-unsigned-byte-in-java –

+0

我在https://stackoverflow.com/a/46861817/1140304上寫了完整的答案 – MiladAhmadi

+0

Hi @MiladAhmadi。感謝您的貢獻。 – dani77

回答

0

解決辦法是在這裏:

3DES Decryption Error Invalid Key Length

我刪除了消息摘要密鑰生成和我用這個代碼:

private byte[] genTwoKey3DES(byte[] key) { 
    byte[] keyAux; 
    if (key.length == 16) { 
     keyAux = new byte[24]; 
     System.arraycopy(key, 0, keyAux, 0, 16); 
     System.arraycopy(key, 0, keyAux, 16, 8); 
    } else { 
     keyAux = key; 
    } 
    return keyAux; 
}