`

[C# & Java].Net加密(DESCryptoServiceProvider) VS. Java解密

 
阅读更多

前言:這邊只列出我工作上有遇到的情況,並未對所有的加解密做很完整的舉例/說明。
不過如果有人能提供其他情況,我是可以試著去解看看。

情境:在.Net中,利用DESCryptoServiceProvider進行加密。加密的Mode為ECB,Padding為None、Zeros與PKCS7。
Java用到的import如下:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64;

.Net加密的程式如下:PaddingMode.None

01 //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
02 DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
03 //Key的長度要64bits -> 8bytes;用ASCII編碼將Key轉為byte[]
04 objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
05 objDESCryptoServiceProvider.Mode = CipherMode.ECB;
06 objDESCryptoServiceProvider.Padding = PaddingMode.None;
07
08 //用UTF-8編碼, 將字串轉為byte[]
09 byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.None的測試字串!");
10 //因為PaddingMode.None的關係, byte[]的長度要是8的倍數
11 byte[] bysFixSizeData = new byte[(int)Math.Ceiling(bysData.Length / 8.0) * 8];
12 //將資料複製到長度為8的倍數的byte[]
13 Array.Copy(bysData, bysFixSizeData, bysData.Length);
14
15 //進行加密
16 byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor().TransformFinalBlock(bysFixSizeData, 0, bysFixSizeData.Length);
17 //將byte[]轉為Base64的字串
18 Console.WriteLine(Convert.ToBase64String(bysEncrypted));
19 //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkfvLkf9phS9mW2tbtS6JcMSiwX2N1KbGp

Java解密的程式如下:使用org.apache.commons.codec.binary.Base64這個類別做Base64字串的解碼

try {
    //解密的Key
    String strKey = "12345678";
    //已加密的Base64字串
    String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkfvLkf9phS9mW2tbtS6JcMSiwX2N1KbGp";

    //先將Base64字串轉碼為byte[]
    Base64 objBase64 = new Base64();
    byte[] bysDecoded = objBase64.decode(strEncrypted.getBytes());

    //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做
    DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes("ASCII"));
    SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec);

    //設定一個DES/ECB/NoPadding的Cipher
    //ECB對應到.Net的CipherMode.ECB
    //NoPadding對應到.Net的PaddingMode.None
    Cipher objCipher = Cipher.getInstance("DES/ECB/NoPadding");
    //設定為解密模式, 並設定解密的key
    objCipher.init(Cipher.DECRYPT_MODE, objSecretKey);

    //輸出解密後的字串. 因為加密是用UTF-8將字串轉為byte[], 所以這邊要用UTF-8轉回去
    //注意後面會多一些空字元. 因為加密前有因為資料長度的關係補上一些空的bytes
    //這邊用String的trim()將這些空字元刪掉
    String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8").trim();
    System.out.println("[" + strDecrypted + "]");
    //輸出:[我是一個PaddingMode.None的測試字串!]
} catch (Exception e) {
    e.printStackTrace(System.out);
}

接下來測試一下.Net中的PaddingMode.Zeros:

01 //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
02 DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
03 //Key的長度要64bits -> 8bytes
04 objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
05 objDESCryptoServiceProvider.Mode = CipherMode.ECB;
06 objDESCryptoServiceProvider.Padding = PaddingMode.Zeros;
07
08 //用UTF-8編碼, 將字串轉為byte[]
09 //因為PaddingMode.Zeros的關係, 不用像上一個Sample一樣, 另外弄一個byte[]去將資料補到8的倍數
10 byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.Zeros的測試字串!");
11
12 //進行加密
13 byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor().TransformFinalBlock(bysData, 0, bysData.Length);
14 //將byte[]轉為Base64的字串
15 Console.WriteLine(Convert.ToBase64String(bysEncrypted));
16 //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkYe6Sq5Y3mpq2JD91DLtxC/66itziI0rD

Java的程式不用改變,維持原狀即可。

try {
    //解密的Key
    String strKey = "12345678";
    //已加密的Base64字串
    String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkYe6Sq5Y3mpq2JD91DLtxC/66itziI0rD";

    //先將Base64字串轉碼為byte[]
    Base64 objBase64 = new Base64();
    byte[] bysDecoded = objBase64.decode(strEncrypted.getBytes());
    
    //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做
    DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes("ASCII"));
    SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec);
    
    //設定一個DES/ECB/NoPadding的Cipher
    //ECB對應到.Net的CipherMode.ECB
    //NoPadding一樣可對應到.Net的PaddingMode.Zeros
    Cipher objCipher = Cipher.getInstance("DES/ECB/NoPadding");
    //設定為解密模式, 並設定解密的key
    objCipher.init(Cipher.DECRYPT_MODE, objSecretKey);
    
    //輸出解密後的字串. 注意一樣會多一些空字元. 因為加密時有指定PaddingMode.Zeros, 所以會自動補空字元
    //這邊一樣用String的trim()將這些空字元刪掉
    String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8").trim();
    System.out.println("[" + strDecrypted + "]");
    //輸出:[我是一個PaddingMode.Zeros的測試字串!]
} catch (Exception e) {
    e.printStackTrace(System.out);
}

最後測試.Net中的PaddingMode.PKCS7:

01 //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
02 DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
03 //Key的長度要64bits -> 8bytes
04 objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
05 objDESCryptoServiceProvider.Mode = CipherMode.ECB;
06 objDESCryptoServiceProvider.Padding = PaddingMode.PKCS7;
07
08 //用UTF-8編碼, 將字串轉為byte[]
09 //這邊也不用另外做補資料的動作
10 byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.PKCS7的測試字串!");
11
12 //進行加密
13 byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor().TransformFinalBlock(bysData, 0, bysData.Length);
14 //將byte[]轉為Base64的字串
15 Console.WriteLine(Convert.ToBase64String(bysEncrypted));
16 //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkt86hRLUM4/m2JD91DLtxC5+8Tqc7iB2f

Java程式的差別就在於把DES/ECB/NoPadding改為DES/ECB/PKCS5Padding

try {
    //解密的Key
    String strKey = "12345678";
    //已加密的Base64字串
    String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkt86hRLUM4/m2JD91DLtxC5+8Tqc7iB2f";
    
    //先將Base64字串轉碼為byte[]
    Base64 objBase64 = new Base64();
    byte[] bysDecoded = objBase64.decode(strEncrypted.getBytes());
    
    //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做
    DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes("ASCII"));
    SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec);

    //設定一個DES/ECB/PKCS5Padding的Cipher
    //ECB對應到.Net的CipherMode.ECB
    //用PKCS5Padding對應到.Net的PaddingMode.PKCS7
    Cipher objCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    //設定為解密模式, 並設定解密的key
    objCipher.init(Cipher.DECRYPT_MODE, objSecretKey);
    
    //輸出解密後的字串. 因為加密時指定PaddingMode.PKCS7, 所以可以不用處理空字元
    //不過若想保險點, 也是可以用trim()去處理過一遍
    String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8").trim();
    System.out.println("[" + strDecrypted + "]");
    //輸出:[我是一個PaddingMode.PKCS7的測試字串!]
} catch (Exception e) {
    e.printStackTrace(System.out);
}

因為目前只有這些加解密的需求,所以就沒去測其他的。
也許以後有用到其他的,就再補上

分享到:
评论

相关推荐

    DESCryptoServiceProvider密码加密与解密

    用户注册密码存入数据库经过DESCryptoServiceProvider加密,在用户登录的时候对密码进行解密或者把用户输入的密码再次进行加密查看和数据库是否一样。

    C#加密JAVA解密

    C# 加密 JAVA 解密源码 using System; using System.IO; using System.Security.Cryptography; namespace WindowsApplication1 { /// /// Security 的摘要说明。 /// public class Security { const string...

    c#des加密.zip

    简单常用的加密 byte[] data = Encoding.UTF8.GetBytes(input); using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) { des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); des.IV = ...

    C# ASP.NET - 加密与解密数据库中字段数据

    说明:通过DESCryptoServiceProvider类进行加密和解密数据;

    DESCryptoServiceProvider加密app.config

    winform中对数据库连接字符串的加密解密,string strProvider = "DataProtectionConfigurationProvider"; // string strProvider = "RSAProtectedConfigurationProvider"; 这两种只能在本机加密解密,我上传的代码...

    visual studio 2013 C# DES 加密解密 asp.net 完整 源码 下载

    VS C#2013 DES加密解密完整源代码 测试平台 visual studio 2013 win8.1 依据网上资源整理,并亲测,并写出窗口供调用演示,原代码全部打包奉上,可供学习使用。 public static string EncryptDES(string ...

    Des加密解密C#源码

    Des加密解密C#源码,很实用 byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); byte[] rgbIV = Encoding.ASCII.GetBytes(kesVector); byte[] inputByteArray = Encoding.UTF8.GetBytes...

    c# 加密和解密相关代码

    图19.3 使用ROT13算法加密解密数据 关 键技术 本实例实现时,主要是用Convert 类的ToChar 方法来获取单个字符的Unicode 编码,然后将字母的前13 个和后13 个对调,从而实现加密的功能。下面对Convert类的ToChar 方法...

    源码_C语言实现C#下的DES加密算法.zip

    源码_C语言实现C#下的DES加密算法,支持CBC和ECB两种加密模式

    加密解密类DESEncrypt.cs

    DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] inputByteArray; inputByteArray=Encoding.Default.GetBytes(Text); des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web....

    自己写的DES加密解密 ASP.NET(C#)

    自己写的简单DES加密加密 public partial class _Default : System.Web.UI.Page { private static byte[] Key64 = { 42, 16, 93, 156, 78, 4, 218, 32 }; private static byte[] IV64 = { 55, 103, 246, 79, 36, ...

    Android C# Css Java PHP Python HTML C语言 八大编程语言知识点汇总.zip

    Android C# Css Java PHP Python HTML C语言 八大编程语言知识点汇总: Android各知识点详细总结.pdf C#知识点详细总结.pdf Css知识点归纳总结.pdf C语言各知识点详细总结.pdf HTML知识点汇总.pdf Java各知识点详细...

    C#文件夹加密有源代码!

    深度剖析各种加密方法!源码可直接调试! ublic static void F加密UTF8文件(string sInputFilename, string sOutputFilename, string sKey) { FileStream fsInput = new FileStream(sInputFilename, FileMode....

    MD5加密解密

    MD5 加密 解密 public string EnCode(string data) { byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64); byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64); ...

    des加密C#.

    主要用到C#提供的以下三个类: MemoryStream 内存流 DESCryptoServiceProvider 加密服务提供者类 CryptoStream 讲数据流连接到加密转换的流

    asp.net专家疑难解答200问源码

    193.如何使用DESCryptoServiceProvider类对数据或者文件进行加密解密 194.如何统计在线人数 195.如何在ASP.NET实现验证码 196.如何在本地取得指定网页的源代码 197.如何在ASP.NET中做一个日期选择器 198.如何在...

    asp.net 通用包

    /// 解密密钥,要求为8位,和加密密钥相同 /// 解密成功返回解密后的字符串,失败返源串 public static string Decode(string decryptString, string decryptKey) { try { decryptKey = Utils.GetSubString...

    asp.net专家疑难解答200问

    如何使用DESCryptoServiceProvider类对数据或者文件进行加密解密 194.如何统计在线人数 195.如何在ASP.NET实现验证码 196.如何在本地取得指定网页的源代码 197.如何在ASP.NET中做一个日期选择器 ...

    asp.net TripleDES加密、解密算法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace WindowsFormsApplication1 { #region ...

    密码加密工具

    /// 解密密钥,要求为8位,和加密密钥相同 /// 解密成功返回解密后的字符串,失败返源串 public static string DecryptDES(string decryptString, string decryptKey) { try { decryptKey += "--------"; byte...

Global site tag (gtag.js) - Google Analytics