Другой результат после преобразования программы 3DES из C # в Java - PullRequest
0 голосов
/ 01 октября 2018

У меня есть программа ac # следующим образом:

public static string Encrypt(string sClear, string sKey)
        {
            sClear = "4140700104596085";
            sKey = "222222222222222222222222222222222222222222222222";

            TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
            cryptoProvider.Mode = CipherMode.ECB;

            byte[] bData = new byte[16];
            byte[] bKey = new byte[24];

            // Convert from hex to decimal
            FromHexToDecimal(sClear).CopyTo(bData, 0);
            FromHexToDecimal(sKey).CopyTo(bKey, 0);

            ICryptoTransform cTransform = DESCryptoExtensions.CreateWeakEncryptor(cryptoProvider, bKey, cryptoProvider.IV);
            byte[] result = cTransform.TransformFinalBlock(bData, 0, bData.Length);

            return BitConverter.ToString(result).Replace("-", "").Substring(0, 16);
        }

Мой открытый текст - «4140700104596085», мой ключ - «222222222222222222222222222222222222222222222222», и эта программа выдаст мне «0C90320B7B9EC798» в качестве результата.

Теперь я пытаюсь сделать это в коде Java, и вот мой код:

public static String encryptToString(String message) throws Exception {
      message = "4140700104596085";
      final MessageDigest md = MessageDigest.getInstance("md5");
      final byte[] digestOfPassword = md.digest("222222222222222222222222222222222222222222222222"
              .getBytes("utf-8"));
      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 IvParameterSpec iv = new IvParameterSpec(new byte[8]);
      final Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE, key);
      // cipher.init(Cipher.ENCRYPT_MODE, key, iv);

      final byte[] plainTextBytes = message.getBytes("utf-8");
      final byte[] cipherText = cipher.doFinal(plainTextBytes);

      return Hex.encodeHexString(cipherText).substring(0, 16);
  }

Как вы можете видеть, я комментирую cipher.init(Cipher.ENCRYPT_MODE, key, iv);, потому что я нажму java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV ошибку,

Даже если я это прокомментирую, результат, который я получаю, будет другим, это f8f8739fb41259d6.Я считаю, что в моем коде на Java что-то не так, есть идеи?

Я попробовал Google, но переводить не так просто.

1 Ответ

0 голосов
/ 01 октября 2018

Я нашел решение.

Я должен следовать коду в C #.

Таким образом, я удаляю

final MessageDigest md = MessageDigest.getInstance("md5");
      final byte[] digestOfPassword = md.digest("222222222222222222222222222222222222222222222222"
              .getBytes("utf-8"));
      final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
      for (int j = 0, k = 16; j < 8;) {
          keyBytes[k++] = keyBytes[j++];
      }

И заменяю на

final byte[] keyBytes = fromHexToDecimal("222222222222222222222222222222222222222222222222");

И метод fromHexToDecimal будет следующим:

public static byte[] fromHexToDecimal(String hex) {

      int len = hex.length() / 2;
      byte[] result = new byte[len];

      for (int i = 0, j = 0; i < len; i++, j = j + 2) {
        StringBuilder c = new StringBuilder();
        c = c.append(hex.charAt(j)).append(hex.charAt(j+1));
        short s = (short) Integer.parseInt(c.toString(), 16);
        result[i] = (byte)(s & 0xff);
      }


      return result;
    }
...