none
加解密(.Net & Java) RRS feed

  • 問題

  • 利用Java加密cookie值

    import java.security.Security;

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;

    /**
     * Basic symmetric encryption example with padding and ECB using DES
     */
    public class MainClass {
      public static void main(String[] args) throws Exception {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());       
        byte[] input = "SHVuZ2hzaUNoZW4=".getBytes();

        byte[] keyBytes = "abcdefghijklmnopqrstuvwx".getBytes();

        SecretKeySpec key = new SecretKeySpec(keyBytes, "TripleDES");
        Cipher cipher = Cipher.getInstance("TripleDES/ECB/NoPadding");
        System.out.println("input : " + new String(input));

        // encryption pass
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
        System.out.println("cipher: " + new String(cipherText) + " bytes: " + ctLength);

        // decryption pass

        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
        int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
        ptLength += cipher.doFinal(plainText, ptLength);
        System.out.println("plain : " + new String(plainText) + " bytes: " + ptLength);
      }
    }

    無法用.Net解密

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

    namespace ConsoleDemo
    {
        class Program
        {
            static void Main(string[] args)
            {


                string plainText = "ABC";
                Console.WriteLine("plainText:" + plainText);

                byte[] buffer = ASCIIEncoding.ASCII.GetBytes(plainText);
                string plainTextBase64 = Convert.ToBase64String(buffer);
                Console.WriteLine("plainTextBase64:" + plainTextBase64+"|");


                TripleDES des = new TripleDESCryptoServiceProvider();
                string keyString = "abcdefghijklmnopqrstuvwx";
                Console.WriteLine("keyString = " + keyString );

                byte[] keyBytes = ASCIIEncoding.ASCII.GetBytes(keyString);
                string keyStringBase64 = Convert.ToBase64String(keyBytes);
                Console.WriteLine("keyStringBase64:" + keyStringBase64);


                des.Mode = CipherMode.ECB;
                //des.Padding = PaddingMode.PKCS7;


                //des.GenerateKey();
                des.Key = keyBytes;
                //des.GenerateIV();


                string tmpString = ASCIIEncoding.ASCII.GetString(des.Key);
                Console.WriteLine(tmpString);

                string encryptedString = Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));
                Console.WriteLine("encryptedString = " + encryptedString);

                buffer = Convert.FromBase64String(encryptedString);
                string decryptedString = ASCIIEncoding.ASCII.GetString(des.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length));
                Console.WriteLine("decryptedString = " + decryptedString);


            }
        }
    }

    請問有解嗎?

    2006年9月25日 上午 04:41

解答

  • 你在java的getBytes的地方,要加入編碼方式,與.NET的ASCII編碼方式要相同才可以

    下面是我改寫你的code,由java加密,將密文寫到檔案後,由.NET讀取並解密,證實是正確的,提供給你參考。

     

    JAVA加密到d:\encrypted.dat:

    import java.security.Security;

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    /**
     * @author lcm
     *
     */
    public class MyTest {

        public static void main(String[] args) throws Exception
        {
            Security.addProvider(new com.sun.crypto.provider.SunJCE());       
            byte[] input = "ABCDEFG=".getBytes("US-ASCII");

            byte[] keyBytes = "abcdefghijklmnopqrstuvwx".getBytes("US-ASCII");

            SecretKeySpec key = new SecretKeySpec(keyBytes, "TripleDES");
            Cipher cipher = Cipher.getInstance("TripleDES/ECB/NoPadding");

            // encryption pass
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
            int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
            ctLength += cipher.doFinal(cipherText, ctLength);
           
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\encrypted.dat"));
           
            bos.write(cipherText);
            bos.flush();
            bos.close();
        }
    }

     

    .NET讀取d:\encrypted.dat進行解密:

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

    namespace TestConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                TripleDES des = new TripleDESCryptoServiceProvider();
                string keyString = "abcdefghijklmnopqrstuvwx";
                Console.WriteLine("keyString = " + keyString);

                byte[] keyBytes = ASCIIEncoding.ASCII.GetBytes(keyString);

                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.None;

                des.Key = keyBytes;

                System.IO.BinaryReader br = new System.IO.BinaryReader(new System.IO.FileStream("d:\\encrypted.dat", System.IO.FileMode.OpenOrCreate));

                byte[] cipherText = br.ReadBytes(1000); // 懶得算size,所以用1000通吃
                ICryptoTransform desTrans = des.CreateDecryptor();
                string decryptedString = ASCIIEncoding.ASCII.GetString(desTrans.TransformFinalBlock(cipherText, 0, cipherText.Length));
                Console.WriteLine("decryptedString = " + decryptedString);

                br.Close();
            }
        }
    }

    2006年9月26日 上午 03:43
  • 謝謝nomoney大大的解答,

    順便把我試的結果讓大家參考一下,原來

    Java

    byte[]tdesKeyData={
    (byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
    (byte)0x67,(byte)0x68,(byte)0x69,(byte)0x6A,(byte)0x6B,(byte)0x6C,
    (byte)0x6D,(byte)0x6E,(byte)0x6F,(byte)0x70,(byte)0x71,(byte)0x72,
    (byte)0x73,(byte)0x74,(byte)0x75,(byte)0x76,(byte)0x77,(byte)0x78};

    byte[]myIV={(byte)50,(byte)51,(byte)52,(byte)53,(byte)54,(byte)55,(byte)56,(byte)57};
    Cipherc3des=Cipher.getInstance("DESede/CBC/PKCS5Padding");
    SecretKeySpecmyKey=newSecretKeySpec(tdesKeyData,"DESede");
    IvParameterSpecivspec=newIvParameterSpec(myIV);
    c3des.init(Cipher.ENCRYPT_MODE,myKey,ivspec);

     

    .Net

    stringkeyString="abcdefghijklmnopqrstuvwx";
    des.Padding=PaddingMode.PKCS7;
    byte[]myIV={(byte)50,(byte)51,(byte)52,(byte)53,(byte)54,(byte)55,(byte)56,(byte)57};
    des.IV=myIV;des.Mode=CipherMode.CBC;stringkeyString="abcdefghijklmnopqrstuvwx";

    是相同的

    2006年9月28日 上午 08:44

所有回覆

  • 有什麼錯誤嗎...我run起來沒有任何問題啊
    2006年9月25日 上午 05:04
  • run起來OK,

    不過.Net加密的資料, Java解不出來

    而Java加密的資料, Net也解不出來

     

    2006年9月25日 上午 05:09
  • 你在java的getBytes的地方,要加入編碼方式,與.NET的ASCII編碼方式要相同才可以

    下面是我改寫你的code,由java加密,將密文寫到檔案後,由.NET讀取並解密,證實是正確的,提供給你參考。

     

    JAVA加密到d:\encrypted.dat:

    import java.security.Security;

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    /**
     * @author lcm
     *
     */
    public class MyTest {

        public static void main(String[] args) throws Exception
        {
            Security.addProvider(new com.sun.crypto.provider.SunJCE());       
            byte[] input = "ABCDEFG=".getBytes("US-ASCII");

            byte[] keyBytes = "abcdefghijklmnopqrstuvwx".getBytes("US-ASCII");

            SecretKeySpec key = new SecretKeySpec(keyBytes, "TripleDES");
            Cipher cipher = Cipher.getInstance("TripleDES/ECB/NoPadding");

            // encryption pass
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
            int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
            ctLength += cipher.doFinal(cipherText, ctLength);
           
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\encrypted.dat"));
           
            bos.write(cipherText);
            bos.flush();
            bos.close();
        }
    }

     

    .NET讀取d:\encrypted.dat進行解密:

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

    namespace TestConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                TripleDES des = new TripleDESCryptoServiceProvider();
                string keyString = "abcdefghijklmnopqrstuvwx";
                Console.WriteLine("keyString = " + keyString);

                byte[] keyBytes = ASCIIEncoding.ASCII.GetBytes(keyString);

                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.None;

                des.Key = keyBytes;

                System.IO.BinaryReader br = new System.IO.BinaryReader(new System.IO.FileStream("d:\\encrypted.dat", System.IO.FileMode.OpenOrCreate));

                byte[] cipherText = br.ReadBytes(1000); // 懶得算size,所以用1000通吃
                ICryptoTransform desTrans = des.CreateDecryptor();
                string decryptedString = ASCIIEncoding.ASCII.GetString(desTrans.TransformFinalBlock(cipherText, 0, cipherText.Length));
                Console.WriteLine("decryptedString = " + decryptedString);

                br.Close();
            }
        }
    }

    2006年9月26日 上午 03:43
  • 謝謝nomoney大大的解答,

    順便把我試的結果讓大家參考一下,原來

    Java

    byte[]tdesKeyData={
    (byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
    (byte)0x67,(byte)0x68,(byte)0x69,(byte)0x6A,(byte)0x6B,(byte)0x6C,
    (byte)0x6D,(byte)0x6E,(byte)0x6F,(byte)0x70,(byte)0x71,(byte)0x72,
    (byte)0x73,(byte)0x74,(byte)0x75,(byte)0x76,(byte)0x77,(byte)0x78};

    byte[]myIV={(byte)50,(byte)51,(byte)52,(byte)53,(byte)54,(byte)55,(byte)56,(byte)57};
    Cipherc3des=Cipher.getInstance("DESede/CBC/PKCS5Padding");
    SecretKeySpecmyKey=newSecretKeySpec(tdesKeyData,"DESede");
    IvParameterSpecivspec=newIvParameterSpec(myIV);
    c3des.init(Cipher.ENCRYPT_MODE,myKey,ivspec);

     

    .Net

    stringkeyString="abcdefghijklmnopqrstuvwx";
    des.Padding=PaddingMode.PKCS7;
    byte[]myIV={(byte)50,(byte)51,(byte)52,(byte)53,(byte)54,(byte)55,(byte)56,(byte)57};
    des.IV=myIV;des.Mode=CipherMode.CBC;stringkeyString="abcdefghijklmnopqrstuvwx";

    是相同的

    2006年9月28日 上午 08:44