三重DES加密C# - 用Java解密 [英] Triple DES Encrypt C# - Decrypt in Java

查看:262
本文介绍了三重DES加密C# - 用Java解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从客户端服务器获取一个Triple DES解密字符串,该字符串已用c#编码(见下文):

I'm getting a Triple DES decrypted string from the clients server, which has been coded in c# (see below):

using System.IO;
using System;
using System.Security.Cryptography;
using System.Collections;
using System.Text;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");

    var encryption = TripleDESEncrypt("12345678901234", "C9AF269DF8A78A06D1216BFFF8F0536A");
      Console.WriteLine(encryption);

    }

      public static string TripleDESEncrypt(string strClearText, string strKey)
        {
            byte[] bytClearText;
            byte[] bytClearTextChunk = new byte[8];
            byte[] bytEncryptedChunk = new byte[8];
            int BytesCount = 0;
            int nArrayPosition = 0;
            string strEncryptedChar;
            string strEncryptedText = "";

            ArrayList Input = new ArrayList();
            ArrayList Output = new ArrayList();

            TripleDESCryptoServiceProvider tdes = (TripleDESCryptoServiceProvider)TripleDESCryptoServiceProvider.Create();

            tdes.Key = HexToByteArray(strKey);
            tdes.Mode = CipherMode.ECB;

            ICryptoTransform tdesEncrypt = tdes.CreateEncryptor();

            bytClearText = ASCIIEncoding.ASCII.GetBytes(strClearText);
            BytesCount = bytClearText.Length;

            for (int i = 0; i < BytesCount; i++)
            {
                if (nArrayPosition == 8)
                {
                    Input.Add(bytClearTextChunk);
                    bytClearTextChunk = new byte[8];
                    nArrayPosition = 0;
                }
                bytClearTextChunk[nArrayPosition] = bytClearText[i];
                nArrayPosition++;
            }

            if (nArrayPosition != 0)
                Input.Add(bytClearTextChunk);


            foreach (byte[] Cbyte in Input)
            {
                tdesEncrypt.TransformBlock(Cbyte, 0, 8, bytEncryptedChunk, 0);
                Output.Add(bytEncryptedChunk);
                bytEncryptedChunk = null;
                bytEncryptedChunk = new byte[8];
            }


            foreach (byte[] Cbyte in Output)
            {
                foreach (byte BByte in Cbyte)
                {
                    strEncryptedChar = BByte.ToString("X");
                    strEncryptedChar = strEncryptedChar.PadLeft(2, Convert.ToChar("0"));
                    strEncryptedText += strEncryptedChar;
                }
            }

            return strEncryptedText;
        }
        private static byte[] HexToByteArray(string strHex)
        {
            byte[] bytArray = new byte[strHex.Length / 2];
            int positionCount = 0;

            for (int i = 0; i < strHex.Length; i += 2)
            {
                bytArray[positionCount] = byte.Parse(strHex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
                positionCount++;
            }
            return bytArray;
        }
}

然后我尝试使用Java对Triple DES进行解密使用此键: C9AF269DF8A78A06D1216BFFF8F0536A

I am then trying to Triple DES decrypt it in Java using this key: C9AF269DF8A78A06D1216BFFF8F0536A

这是我要解密的代码:

public String DesDecryptPin(String pin, String encryptKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

        String UNICODE_FORMAT = "UTF8";
        String decryptedPinText = null;

        byte[] hexConvert = hexStringtoByteArray(encryptKey);

        SecretKey desKey = null;
        byte[] tdesKey = new byte[24];
        System.arraycopy(hexConvert, 0, tdesKey, 0,16);
        System.arraycopy(hexConvert, 0, tdesKey, 0,8);

        byte[] encryptKeyBytes = encryptKey.getBytes(UNICODE_FORMAT);

        KeySpec desKeySpec = new DESedeKeySpec(tdesKey);
        Cipher desCipher;
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
        desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
        try {
            desKey = skf.generateSecret(desKeySpec);
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        desCipher.init(Cipher.DECRYPT_MODE, desKey);

       byte[] decryptPin = desCipher.doFinal(pin.getBytes());
        decryptedPinText = new String(decryptPin, "UTF-8");
        return decryptedPinText;
    }

输出/输出的样本输出将是12345678901234然而,我得到了混乱的废话,例如 0 8 /0

所以c#之间有些东西丢失了和java ...
这是我上一个问题的后续问题这里

The sample out put would be input/output would be "12345678901234" however, I'm getting jumbled nonsense returned e.g ��0�8��/0��

So something is getting lost between c# and java... This is a follow on from a previous question I asked here

我很感激这方面的帮助

对代码的更改

changes to code

   public String DesDecryptPin(String pin, String encryptKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

        String UNICODE_FORMAT = "UTF8";
        String decryptedPinText = null;



        SecretKey desKey = null;
        byte[] encryptKeyBytes = EncodingUtils.getAsciiBytes(encryptKey);
        byte[] tdesKey = new byte[24];
        System.arraycopy(encryptKeyBytes, 8, tdesKey, 0, 8);
        System.arraycopy(encryptKeyBytes, 0, tdesKey, 8, 16);
        KeySpec desKeySpec = new DESedeKeySpec(tdesKey);
        Cipher desCipher;
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
        desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
        try {
            desKey = skf.generateSecret(desKeySpec);
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        desCipher.init(Cipher.DECRYPT_MODE, desKey);

        byte[] decryptPin = desCipher.doFinal(EncodingUtils.getAsciiBytes(pin));

        decryptedPinText = new String(decryptPin, "ASCII");
        return decryptedPinText;
    }

c#decrypt code

c# decrypt code

using System.IO;
using System;
using System.Security.Cryptography;
using System.Collections;
using System.Text;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");

        var encryption = TripleDESDecrypt("1D30CC3DE1641D7F5E821D13FC1200C3", "C9AF269DF8A78A06D1216BFFF8F0536A");
        Console.WriteLine(encryption);

    }

      public static string TripleDESDecrypt(string strEncryptedText, string strKey)
        {
            string errorMessage = "";
            int errorCode = 0;
            string strDecryptedText = "";

            try
            {
                byte[] bytEncryptedChunk = new byte[8];
                byte[] bytClearTextChunk = new byte[8];
                byte[] _bytesEmpty = new byte[8];
                int BytesCount = 0;
                int positionCount = 0;


                ArrayList Input = new ArrayList();
                ArrayList Output = new ArrayList();

                TripleDESCryptoServiceProvider tdes = (TripleDESCryptoServiceProvider)TripleDESCryptoServiceProvider.Create();

                tdes.Key = HexToByteArray(strKey);
                tdes.Mode = CipherMode.ECB;

                ICryptoTransform tdesDecrypt = tdes.CreateDecryptor();

                BytesCount = strEncryptedText.Length;

                for (int i = 0; i < BytesCount; i += 2)
                {
                    if (positionCount == 8)
                    {
                        positionCount = 0;
                        Input.Add(bytEncryptedChunk);
                        bytEncryptedChunk = new byte[8];
                    }

                    bytEncryptedChunk[positionCount] = byte.Parse(strEncryptedText.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
                    positionCount++;
                }

                if (positionCount != 0)
                {
                    Input.Add(bytEncryptedChunk);
                }

                foreach (byte[] Cbyte in Input)
                {
                    tdesDecrypt.TransformBlock(Cbyte, 0, 8, _bytesEmpty, 0);
                    tdesDecrypt.TransformBlock(Cbyte, 0, 8, bytClearTextChunk, 0);
                    Output.Add(bytClearTextChunk);
                    bytClearTextChunk = null;
                    bytClearTextChunk = new byte[8];
                }

                foreach (byte[] Cbyte in Output)
                {
                    strDecryptedText += ASCIIEncoding.ASCII.GetString(Cbyte);
                }
            }
            catch (Exception ex)
            {
                errorCode = 1;
                errorMessage = ex.Message;


            }
Console.WriteLine(strDecryptedText);
            return strDecryptedText;
        }

        private static byte[] HexToByteArray(string strHex)
        {
            byte[] bytArray = new byte[strHex.Length / 2];
            int positionCount = 0;

            for (int i = 0; i < strHex.Length; i += 2)
            {
                bytArray[positionCount] = byte.Parse(strHex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
                positionCount++;
            }
            return bytArray;
        }
}

这将返回输入加密的内容12345678901234

This returns what is inputting into the encrypt 12345678901234

推荐答案

在C#代码中,使用ASCII:

In your C# code, you use ASCII:

bytClearText = ASCIIEncoding.ASCII.GetBytes(strClearText);

在Java中使用UNICODE:

While in Java you use UNICODE:

byte[] encryptKeyBytes = encryptKey.getBytes(UNICODE_FORMAT);

尝试更改C#以使用UNICODE或java代码来使用ASCII。

Try to change your C# to use UNICODE or your java code to use ASCII.

此外,由于C#填充输出:

Also, since the C# is padding the output :

strEncryptedChar = strEncryptedChar.PadLeft(2, Convert.ToChar("0"));

您可能必须检查以删除加密字符串中的所有'00',因此1D30CC3DE1641D7F5E821D13FC12 00 C3将变为1D30CC3DE1641D7F5E821D13FC12C3

You probably must check to remove all the '00' in the crypted string, so 1D30CC3DE1641D7F5E821D13FC1200C3 will become 1D30CC3DE1641D7F5E821D13FC12C3

(您必须检查它是否在十六进制表达式的边界内:1C01A1应该被修改,因为它有一个填充在第二个Hexa 1C 0 1 A1:1C1A1

(you must check if it's in the boundaries of an hex expression: 1C01A1 should probably be modified since it got a padding on the second Hexa 1C 01 A1: 1C1A1

这篇关于三重DES加密C# - 用Java解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆