3DES从C#加密到JAVA - java

我在C#中有此代码,我需要将其迁移到Java。
我需要使用3DES加密。这是强制性的。

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};

爪哇

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之间,而在C#中,字节原语可以包含255个数字。
数据和关键变量的值是从相同的十六进制字符串到字节的转换获得的。

我需要Java代码返回与C#代码相同的值。
此时,以下值为返回值:

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

两种结果之间我没有任何共同之处。

参考方案

解决方案在这里:

3DES Decryption Error Invalid Key Length

我删除了MessageDigest密钥生成,并使用了以下代码:

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;
} 

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

字符串到字节的转换 - java

如何将字符串转换为字节?例如,Byte.parseByte("255");导致NumberFormatException,因为(出于某种奇怪的原因)byte在Java中是signed,因此它可以具有的最大值是127。所以我需要一个这样的功能public static byte toByte(String input) { ... } 例如…

Java-搜索字符串数组中的字符串 - java

在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…

Java Scanner读取文件的奇怪行为 - java

因此,在使用Scanner类从文件读取内容时,我遇到了一个有趣的问题。基本上,我试图从目录中读取解析应用程序生成的多个输出文件,以计算一些准确性指标。基本上,我的代码只是遍历目录中的每个文件,并使用扫描仪将其打开以处理内容。无论出于何种原因,扫描程序都不会读取其中的一些文件(所有UTF-8编码)。即使文件不是空的,scanner.hasNextLine()在…

Java:正则表达式模式匹配器是否有大小限制? - java

我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)