用 Java 解密 C# 加密的数据(DES)(转)
今天遇到java解密url的问题。我们的系统要获取外部传过来的URL,URL是采用 DES 算法对消息进行加密,再用 BASE64 编码。不过对方系统是用 C# 写的。
在网上搜了几篇文章终于找到一篇可以解决了,感谢这位老兄。
[原文地址:http://yilinliu.blogspot.com/2010/07/c-java-net-descryptoserviceprovider-vs.html]
前言: 這邊只列出我工作上有遇到的情況, 並未對所有的加解密做很完整的舉例/說明.
不過如果有人能提供其他情況, 我是可以試著去解看看.
情境: 在 .Net 中, 利用 DESCryptoServiceProvider 進行加密. 加密的 Mode 為 ECB, Padding 為 None, Zeros 與 PKCS7。
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 //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
//Key的長度要64bits -> 8bytes;用ASCII編碼將Key轉為byte[]
objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
objDESCryptoServiceProvider.Mode = CipherMode.ECB;
objDESCryptoServiceProvider.Padding = PaddingMode.None; //用UTF-8編碼, 將字串轉為byte[]
byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.None的測試字串!");
//因為PaddingMode.None的關係, byte[]的長度要是8的倍數
byte[] bysFixSizeData = new byte[(int)Math.Ceiling(bysData.Length / 8.0) * 8];
//將資料複製到長度為8的倍數的byte[]
Array.Copy(bysData, bysFixSizeData, bysData.Length); //進行加密
byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor()
.TransformFinalBlock(bysFixSizeData, 0, bysFixSizeData.Length);
//將byte[]轉為Base64的字串
Console.WriteLine(Convert.ToBase64String(bysEncrypted));
//輸出: 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:
//建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
//Key的長度要64bits -> 8bytes
objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
objDESCryptoServiceProvider.Mode = CipherMode.ECB;
objDESCryptoServiceProvider.Padding = PaddingMode.Zeros; //用UTF-8編碼, 將字串轉為byte[]
//因為PaddingMode.Zeros的關係, 不用像上一個Sample一樣, 另外弄一個byte[]去將資料補到8的倍數
byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.Zeros的測試字串!"); //進行加密
byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor()
.TransformFinalBlock(bysData, 0, bysData.Length);
//將byte[]轉為Base64的字串
Console.WriteLine(Convert.ToBase64String(bysEncrypted));
//輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkYe6Sq5Y3mpq2JD91DLtxC/66itziI0rD
Java 的程式不用改變, 維持原狀即可.
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.PKCS7:
//建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider
DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider();
//Key的長度要64bits -> 8bytes
objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("12345678");
objDESCryptoServiceProvider.Mode = CipherMode.ECB;
objDESCryptoServiceProvider.Padding = PaddingMode.PKCS7; //用UTF-8編碼, 將字串轉為byte[]
//這邊也不用另外做補資料的動作
byte[] bysData = Encoding.UTF8.GetBytes("我是一個PaddingMode.PKCS7的測試字串!"); //進行加密
byte[] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor()
.TransformFinalBlock(bysData, 0, bysData.Length);
//將byte[]轉為Base64的字串
Console.WriteLine(Convert.ToBase64String(bysEncrypted));
//輸出: 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);
}
用 Java 解密 C# 加密的数据(DES)(转)的更多相关文章
- c#加密,java解密(3DES加密)
c#代码 using System; using System.Security; using System.Security.Cryptography; using System.IO; using ...
- 【知识积累】DES算法之C#加密&Java解密
一.前言 在项目需要添加安全模块,客户端调用服务端发布的service必须要经过验证,加密算法采用DES,客户端采用C#进行加密,服务端使用Java进行解密.废话不多说,直接上代码. 二.客户端 客户 ...
- Java Des加解密方法(c#加密Java解密)
最近我们用Java把一个用.net编写的老系统重新做了翻版,但是登录还是用.net的登录.这样就会遇到一个比较棘手的问题,我们登录用的cookie信息都是.net用des加密的,但我们不得不用Java ...
- PHP DES解密 对应Java SHA1PRNG方式加密
背景及问题 背景:在和外部系统通过HTTP方式跳转时, 为保障传输参数安全性, 采用AES 加密参数. 关于对称加密中 AES, DES, CBC, ECB, PKCS5Padding 概念可参考ht ...
- 利用DES,C#加密,Java解密代码
//C#加密 /// <summary> /// 进行DES加密. /// </summary> /// <param name="pToEncrypt&quo ...
- DES c#加密后java解密
public static String byteArr2HexStr(byte[] bytIn) { StringBuilder builder = new StringBuilder(); for ...
- Java中3DES加密解密与其他语言(如C/C++)通信
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 对称加密----AES和DES加密、解密
目前主流的加密方式有:(对称加密)AES.DES (非对称加密)RSA.DSA 调用AES/DES加密算法包最精要的就是下面两句话: Cipher cipher = Cipher.get ...
- Java常用的加密解密类(对称加密类)
Java常用的加密解密类 原文转载至:http://blog.csdn.net/wyc_cs/article/details/8793198 原创 2013年04月12日 14:33:35 1704 ...
随机推荐
- Idea中一些常用设置
idea展开和折叠方法的快捷键 Ctrl+”+/-”,当前方法展开.折叠Ctrl+Shift+”+/-”,全部展开.折叠 idea中也有自定代码块的功能 //region 描述.....业务代码//e ...
- Codeforces Round #550 (Div. 3) F. Graph Without Long Directed Paths
F. Graph Without Long Directed Paths time limit per test 2 seconds memory limit per test 256 ...
- luoguP1131
时态同步 ...这道题我也不知道咋\(A\)的. 思路: \(anst\) 距离 \(s\) 的最长距离,\(ansp\) 某一节点到祖先所有边的权值和这些些加过的权值和 先求出到\(s\)距离最长的 ...
- mongodb基本的配置和使用
一.连接配置,使用自动配置方式,在applicaiton.properties中配置连接信息即可 spring.data.mongodb.host=127.0.0.1 //连接地址 spring.da ...
- JSP随记
JSP简介: JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun公司倡导.许多公司参与一起建立的一种动态网页技术标准. Se ...
- Java 关于类的构造方法的一点认识
2019年4月21日 星期天 在ORACLE官网上提供的The Java™ Tutorials中,有一节课Providing Constructors for Your Classes(为你的类提供构 ...
- 关于DataTable 判断 列名是否存在的方法中英文符合不区分?
最近系统出现一个错误,排查了很久,发现判断DataTable 列名是否存在时,发现一个坑,居然不会区分中英文符合. 有谁知道其中的原理?先记录一下,免得以后忘记这个天坑. 一. 先初始化一个DataT ...
- SpringBoot的事件监听
事件监听的流程分为三步:1.自定义事件,一般是继承ApplicationEvent抽象类.2.定义事件监听器,一般是实现ApplicationListener接口.3.a.启动的时候,需要将监听器加入 ...
- 原生JS插件(超详细)
作为一个前端er,如果不会写一个小插件,都不好意思说自己是混前端界的.写还不能依赖jquery之类的工具库,否则装得不够高端.那么,如何才能装起来让自己看起来逼格更高呢?当然是利用js纯原生的写法啦. ...
- Python学习(四十二)—— Djago-model进阶
一.QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. Entry.objects.all()[:5] # (LIMI ...