- 浏览: 190238 次
文章分类
- 全部博客 (84)
- 感悟摘抄 (3)
- 数据库 (13)
- 前线知识 (1)
- Jsp (2)
- JS (3)
- 面试题目 (1)
- 大数据学习 (1)
- Java总结 (3)
- Web知识 (2)
- Maven (4)
- Linux (4)
- Tomcat (6)
- Hibernate (2)
- Spring (4)
- Logger (1)
- Exceptions (3)
- ActiveMq (1)
- Thinking in Java (9)
- Java工具类 (7)
- 代码优化 (1)
- 源码解析 (1)
- 算法学习 (1)
- Rabbitmq (2)
- 一点感悟 (3)
- Mybatis (1)
- 代码编译错误 (2)
- Eclipse (4)
最新评论
-
guooo:
老乡兄弟有感而发啊
一点感悟(一) 初识 -
a3x60:
真不错!!!
Java 生成随机数 -
qindongliang1922:
支持河南老乡
一点感悟(一) 初识 -
InJavaWeTrust:
加油
一点感悟(一) 初识 -
感受微风:
city_moon 写道ID如果不是数字类型的呢?比如是UUI ...
mysql 删除重复数据只保留一条
C端同事给的密文(十六进制)是32位,但是我这边生成的是48位
刚开始工具类中使用的
Cipher cipher=Cipher.getInstance("DESede");
后来把这个改为
Cipher cipher=Cipher.getInstance("DESede/ECB/NoPadding");
生成的32位 与C端相同
Java 解密、工具类 见下文
Java 官方附录:http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator
Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");
以前写的代码,给的参数都是DES或DESede。实际上DESede是简写,它与DESede/ECB/PKCS5Padding等价。这个参数分为三段。
- 第一段是加密算法的名称,如DESede实际上是3-DES。这一段还可以放其它的对称加密算法,如Blowfish等。
- 第二段是分组加密的模式,除了CBC和ECB之外,还可以是NONE/CFB/QFB等。最常用的就是CBC和ECB了。DES采用分组加密的方式,将明文按8字节(64位)分组分别加密。如果每个组独立处理,则是ECB。CBC的处理方式是先用初始向量IV对第一组加密,再用第一组的密文作为密钥对第二组加密,然后依次完成整个加密操作。如果明文中有两个分组的内容相同,ECB会得到完全一样的密文,但CBC则不会。
- 第三段是指最后一个分组的填充方式。大部分情况下,明文并非刚好64位的倍数。对于最后一个分组,如果长度小于64位,则需要用数据填充至64位。PKCS5Padding是常用的填充方式,如果没有指定,默认的方式就是它。
补充一点,虽然DES的有效密钥长度是56位,但要求密钥长度是64位(8字节)。3DES则要求24字节。
出处:http://www.cnblogs.com/qkhh/p/4683626.html
MODE指的是加密模式。加密算法是按块进行加密的,DES是64bit(8 bytes)一个块进行加密,每次输入8个字节的明文,输出8个字节密文,如果是明文一共16个字节长,则分成两组依次进行加密。
(1) 例如明文是 1234567812345678,那么加密的结果类似C21431262C779CC21431262C779C,看出了什么没,是的,重复了两遍,这钟MODE就是ECB。分组之间没有联系,组和组明文相同,那么密文也是相同的,容易被发现规律。
(2)为了解决这个问题,出现了新的加密模式,分组连接模式(CBC),密码反馈模式(CFB),输出反馈模式(OFB)。
CBC 是需要给一个初始化的向量,然后将每个输出与该向量作运算,并将运算的结果作为下一个加密块的初始化向量,CFB 和 OFB 则不需要提供初始化向量,直接将密码或者输出作为初始化向量进行计算;避免了明文的规律性出现反应在密文中。当然带来的问题是,解密的时候必须接收完整才能开始解密。如果其中部分信息网络接收出错,会导致整个解密失败,而ECB仅影响网络传输出错的那个块的解密。
其次、解释上段落第3点钟提到的PADDING。padding在这里指填充方式,例如明文是10位,按照8bytes分组,正好1组多2个byte,这2个byte怎么加密?这时候必须对明文进行Padding操作。padding的方式很多,在《跨语言的加解密兼容问题讨论》 一文中有比较想起的对比。
(1)一种PKCS#7,该填充方法是将每一个补充的字节内容填充为填充的字节个数;在这里我们需要填充的6个'0x6';
(2)另一种PKCS#5,和PKCS#7的区别就 是,分组的大小为8个字节。
(3)另外,就是如果明文刚刚好进行分组,那么需要补充一个独立的分组。如 DES明文:12345678,为 8 个字节,则必须补充8个0×08至16个字节,然后进行加密;解密后的字符串为12345678\x08\x08\x08\x08\x08\x08\x08\x08,需要去掉多余的, 0×08的到原文。
出处:http://www.mythroad.net/2012/11/01/3des%E7%AE%97%E6%B3%95java%E4%B8%8Ec%E7%9A%84%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E7%8E%B0/
DESUtil
HexUtil
刚开始工具类中使用的
Cipher cipher=Cipher.getInstance("DESede");
后来把这个改为
Cipher cipher=Cipher.getInstance("DESede/ECB/NoPadding");
生成的32位 与C端相同
Java 解密、工具类 见下文
Java 官方附录:http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator
Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");
以前写的代码,给的参数都是DES或DESede。实际上DESede是简写,它与DESede/ECB/PKCS5Padding等价。这个参数分为三段。
- 第一段是加密算法的名称,如DESede实际上是3-DES。这一段还可以放其它的对称加密算法,如Blowfish等。
- 第二段是分组加密的模式,除了CBC和ECB之外,还可以是NONE/CFB/QFB等。最常用的就是CBC和ECB了。DES采用分组加密的方式,将明文按8字节(64位)分组分别加密。如果每个组独立处理,则是ECB。CBC的处理方式是先用初始向量IV对第一组加密,再用第一组的密文作为密钥对第二组加密,然后依次完成整个加密操作。如果明文中有两个分组的内容相同,ECB会得到完全一样的密文,但CBC则不会。
- 第三段是指最后一个分组的填充方式。大部分情况下,明文并非刚好64位的倍数。对于最后一个分组,如果长度小于64位,则需要用数据填充至64位。PKCS5Padding是常用的填充方式,如果没有指定,默认的方式就是它。
补充一点,虽然DES的有效密钥长度是56位,但要求密钥长度是64位(8字节)。3DES则要求24字节。
出处:http://www.cnblogs.com/qkhh/p/4683626.html
MODE指的是加密模式。加密算法是按块进行加密的,DES是64bit(8 bytes)一个块进行加密,每次输入8个字节的明文,输出8个字节密文,如果是明文一共16个字节长,则分成两组依次进行加密。
(1) 例如明文是 1234567812345678,那么加密的结果类似C21431262C779CC21431262C779C,看出了什么没,是的,重复了两遍,这钟MODE就是ECB。分组之间没有联系,组和组明文相同,那么密文也是相同的,容易被发现规律。
(2)为了解决这个问题,出现了新的加密模式,分组连接模式(CBC),密码反馈模式(CFB),输出反馈模式(OFB)。
CBC 是需要给一个初始化的向量,然后将每个输出与该向量作运算,并将运算的结果作为下一个加密块的初始化向量,CFB 和 OFB 则不需要提供初始化向量,直接将密码或者输出作为初始化向量进行计算;避免了明文的规律性出现反应在密文中。当然带来的问题是,解密的时候必须接收完整才能开始解密。如果其中部分信息网络接收出错,会导致整个解密失败,而ECB仅影响网络传输出错的那个块的解密。
其次、解释上段落第3点钟提到的PADDING。padding在这里指填充方式,例如明文是10位,按照8bytes分组,正好1组多2个byte,这2个byte怎么加密?这时候必须对明文进行Padding操作。padding的方式很多,在《跨语言的加解密兼容问题讨论》 一文中有比较想起的对比。
(1)一种PKCS#7,该填充方法是将每一个补充的字节内容填充为填充的字节个数;在这里我们需要填充的6个'0x6';
(2)另一种PKCS#5,和PKCS#7的区别就 是,分组的大小为8个字节。
(3)另外,就是如果明文刚刚好进行分组,那么需要补充一个独立的分组。如 DES明文:12345678,为 8 个字节,则必须补充8个0×08至16个字节,然后进行加密;解密后的字符串为12345678\x08\x08\x08\x08\x08\x08\x08\x08,需要去掉多余的, 0×08的到原文。
出处:http://www.mythroad.net/2012/11/01/3des%E7%AE%97%E6%B3%95java%E4%B8%8Ec%E7%9A%84%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E7%8E%B0/
DESUtil
import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; public class DESUtil { private static final String Algorithm = "DESede"; //定义 加密算法,可用 DES,DESede,Blowfish private static final String AlgorithmP = "DESede/ECB/NoPadding"; public static String Decrypt3DES(String value, String key) throws Exception { // byte[] b = decryptMode(GetKeyBytes(key), Base64.decode(value)); byte[] b = decryptMode(GetKeyBytes(key), HexUtil.decodeHex(value.toCharArray())); return new String(b); } public static String Encrypt3DES(String value, String key) throws Exception { // String str = byte2Base64(encryptMode(GetKeyBytes(key), value.getBytes())); String str = HexUtil.encodeHexStr(encryptMode(GetKeyBytes(key), value.getBytes())); return str; } //计算24位长的密码byte值,首先对原始密钥做MD5算hash值,再用前8位数据对应补全后8位 public static byte[] GetKeyBytes(String strKey) throws Exception { if (null == strKey || strKey.length() < 1) throw new Exception("key is null or empty!"); byte[] bkey = strKey.getBytes(); int start = bkey.length; byte[] bkey24 = new byte[24]; for (int i = 0; i < start; i++) { bkey24[i] = bkey[i]; } for (int i = start; i < 24; i++) {//为了与.net16位key兼容 bkey24[i] = bkey[i - start]; } return bkey24; } //keybyte为加密密钥,长度为24字节 //src为被加密的数据缓冲区(源) public static byte[] encryptMode(byte[] keybyte, byte[] src) { try { //生成密钥 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm); //加密 Cipher c1 = Cipher.getInstance(AlgorithmP); c1.init(Cipher.ENCRYPT_MODE, deskey); return c1.doFinal(src); } catch (java.security.NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (javax.crypto.NoSuchPaddingException e2) { e2.printStackTrace(); } catch (java.lang.Exception e3) { e3.printStackTrace(); } return null; } //keybyte为加密密钥,长度为24字节 //src为加密后的缓冲区 public static byte[] decryptMode(byte[] keybyte, byte[] src) { try { //生成密钥 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm); //解密 Cipher c1 = Cipher.getInstance(AlgorithmP); c1.init(Cipher.DECRYPT_MODE, deskey); return c1.doFinal(src); } catch (java.security.NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (javax.crypto.NoSuchPaddingException e2) { e2.printStackTrace(); } catch (java.lang.Exception e3) { e3.printStackTrace(); } return null; } //转换成base64编码 public static String byte2Base64(byte[] b) { return Base64.encode(b); } //转换成十六进制字符串 public static String byte2hex(byte[] b) { String hs = ""; String stmp = ""; for (int n = 0; n < b.length; n++) { stmp = (java.lang.Integer.toHexString(b[n] & 0XFF)); if (stmp.length() == 1) hs = hs + "0" + stmp; else hs = hs + stmp; } return hs.toUpperCase(); } /** * 去掉java加密后会在后面自动填充的8位 * @param src * @return */ public static byte[] withoutAutofill(byte[] src){ byte[] newbyte = new byte[src.length-8]; for(int i=0 ; i<newbyte.length;i++){ newbyte[i] = src[i]; } return newbyte; } public static void main(String[] args) throws Exception { String x = Encrypt3DES("12341234","000000000222225678"); System.out.println(x); String y = Decrypt3DES(x, "000000000222225678"); System.out.println(y); } }
HexUtil
public class HexUtil { /** * 用于建立十六进制字符的输出的小写字符数组 */ private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * 用于建立十六进制字符的输出的大写字符数组 */ private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * 将字节数组转换为十六进制字符数组 * * @param data * byte[] * @return 十六进制char[] */ public static char[] encodeHex(byte[] data) { return encodeHex(data, true); } /** * 将字节数组转换为十六进制字符数组 * * @param data * byte[] * @param toLowerCase * <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式 * @return 十六进制char[] */ public static char[] encodeHex(byte[] data, boolean toLowerCase) { return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); } /** * 将字节数组转换为十六进制字符数组 * * @param data * byte[] * @param toDigits * 用于控制输出的char[] * @return 十六进制char[] */ protected static char[] encodeHex(byte[] data, char[] toDigits) { int l = data.length; char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; } /** * 将字节数组转换为十六进制字符串 * * @param data * byte[] * @return 十六进制String */ public static String encodeHexStr(byte[] data) { return encodeHexStr(data, false); } /** * 将字节数组转换为十六进制字符串 * * @param data * byte[] * @param toLowerCase * <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式 * @return 十六进制String */ public static String encodeHexStr(byte[] data, boolean toLowerCase) { return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); } /** * 将字节数组转换为十六进制字符串 * * @param data * byte[] * @param toDigits * 用于控制输出的char[] * @return 十六进制String */ protected static String encodeHexStr(byte[] data, char[] toDigits) { return new String(encodeHex(data, toDigits)); } /** * 将十六进制字符数组转换为字节数组 * * @param data * 十六进制char[] * @return byte[] * @throws RuntimeException * 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 */ public static byte[] decodeHex(char[] data) { int len = data.length; if ((len & 0x01) != 0) { throw new RuntimeException("Odd number of characters."); } byte[] out = new byte[len >> 1]; // two characters form the hex value. for (int i = 0, j = 0; j < len; i++) { int f = toDigit(data[j], j) << 4; j++; f = f | toDigit(data[j], j); j++; out[i] = (byte) (f & 0xFF); } return out; } /** * 将十六进制字符转换成一个整数 * * @param ch * 十六进制char * @param index * 十六进制字符在字符数组中的位置 * @return 一个整数 * @throws RuntimeException * 当ch不是一个合法的十六进制字符时,抛出运行时异常 */ protected static int toDigit(char ch, int index) { int digit = Character.digit(ch, 16); if (digit == -1) { throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index); } return digit; } public static void main(String[] args) { String srcStr = "待转换字符串"; String encodeStr = encodeHexStr(srcStr.getBytes()); String decodeStr = new String(decodeHex(encodeStr.toCharArray())); System.out.println("转换前:" + srcStr); System.out.println("转换后:" + encodeStr); System.out.println("还原后:" + decodeStr); } }
发表评论
-
Java HttpUtil
2017-04-15 20:02 17701 Maven引用 <dependency> ... -
JavaBean和XML 互转工具类
2016-09-13 17:19 4638使用XStream的jar包 http://x-stream ... -
JAVA 判断某个文件中是否包含指定字符串
2016-08-10 10:11 12542public class FindStringInTxt ... -
Java 大数据 取出两列不同的值 生成到文本中
2016-06-20 11:24 2616项目前端商城的订单和后端服务的订单有差异,金额比对不上,Exc ... -
Java 生成随机数
2016-05-13 14:37 1702public class RandomUtil { ... -
Java 工具类:数字左补0
2016-04-07 14:16 3620有朋友给出更6的写法: DecimalFormat 是 ...
相关推荐
3. 解密过程:Java使用RSA私钥或DES密钥加密数据,C#接收并解密。 在实现过程中,还需要注意以下几点: - 对于RSA,确保使用相同的模数和指数进行公钥和私钥的生成。 - 对于DES,由于其密钥长度固定,需要确保在两...
首先,"Delphi与Java互通3Des加解密类(XE2)"是指在Delphi XE2环境下创建了一个3DES加解密的组件或类库,这个组件或类库能够与Java环境下的3DES加解密算法无缝对接。Delphi是RAD(快速应用开发)工具,用于编写...
本篇文章将详细讲解如何在C#中实现与Java的3DES加密以及MD5withRSA签名的对接。 3DES(Triple Data Encryption Algorithm)是一种对称加密算法,它使用了DES(Data Encryption Standard)算法三次,增强了加密强度...
在这个场景中,我们关注的是"crypto-js"库中的DES(Data Encryption Standard)加密与Java的SecretKeyFactory进行解密的对接。DES是一种广泛使用的对称加密算法,它以64位的数据块进行操作,但实际有效密钥长度仅为...
在Java中,实现DES加密通常需要使用`javax.crypto`包中的类,但在这个场景中,我们关注的是与Base64编码相关的部分,因为Base64是用于在网络上传输含有二进制数据的文本格式。在Java 8及更高版本中,`java.util.Base...
php-des-aes加解密对接java时整理的java代码,部分路径改变,密钥等信息删除,基础加密代码未动,有兴趣的小伙伴可以学下看下。
* PHP版DES加解密类 * 可与java的DES(DESede/CBC/PKCS5Padding)加密方式兼容 * */ class CryptDes { var $key; var $iv; function CryptDes($key, $iv){ $this->key = $key; $this->iv = $iv; } function ...
本文说明如何使用 Java 和 Python 两种语言来实现 DES 的加解密。 最近碰到的应用场景是这样的。我们需要对接一个系统 S,系统 S 已经对用户的身份进行了验证,新系统 N 也需要对用户的身份进行验证。采用的身份验证...
在Java环境下复现这些加密解密函数对于开发者来说具有重要意义,可以用于开发与Discuz对接的第三方应用或者进行数据迁移。 首先,让我们详细了解一下`Base64.java`。Base64是一种用64个字符(通常为ASCII字符集的一...
这个过程完全符合Java的AES/ECB/PKCS7Padding加密方式,可以与Java代码无缝对接。 在实际应用中,为了提高安全性,建议使用更复杂的加密模式如CBC(Cipher Block Chaining)或CFB(Cipher Feedback),并且可以使用...
**Java与C#的PBE加密** PBE(Password-Based Encryption)基于密码的加密是一种常见的加密方式,它结合了密钥派生函数(PBKDF)和对称加密算法,如DES(Data Encryption Standard),用于保护数据的安全。在Java和...
该标准由NIST(美国国家标准与技术研究所)于2001年制定,用于替代DES(数据加密标准)。AES256使用256位的密钥对数据进行加密,这使得破解的难度极大,因为理论上需要尝试的密钥数量远远超过宇宙中的原子数量。 在...
- `openssl genrsa -des3 -out shnlap93.key 1024` - `openssl rsa -in shnlap93.key -out shnlap93.key` - `openssl req -new -key shnlap93.key -out shnlap93.csr` 通过以上步骤,我们可以生成用于保护公钥和...
在给定的标题和描述中,提到了两种主要的加密算法:RSA和AES,并且强调了这些C#实现的加密方法已经与其他编程语言(如Java和JavaScript)实现了互通。下面将详细阐述这两种加密算法以及它们在实际应用中的使用。 ...
在这个压缩包"desForC.zip"中,包含的是使用C语言编写的3DES(Triple Data Encryption Standard)和Base64加解密算法的源代码,这些源代码设计得可以与Java语言进行无缝对接。3DES和Base64是两种广泛使用的加密和...
5. **接口文档SJJ1310**:SJJ1310是江南天安定义的一套接口规范,用于指导开发者如何与EHSM和EVSM进行通信,实现数据加解密、密钥管理、证书操作等功能。这份文档通常包含API接口定义、调用流程、错误处理机制等内容...
这个jar包包含了实现解密协议的关键算法,确保了在企业号与企业内部系统交互时的数据安全。 在微信企业号的应用开发中,安全是至关重要的。为了保护用户隐私和企业信息安全,微信提供了加密机制,使得在传输过程中...
CryptoJS v3.1.9是一个JavaScript库,专门用于实现各种加密算法,包括AES(Advanced Encryption Standard),它在JavaWeb项目中扮演着重要的角色,实现了前端JS加密和后台Java解密的无缝对接。 一、AES加密算法介绍...
### Java算法集锦:深入解析Java经典算法 #### 单钥密码体制:高效与安全的双刃剑 在Java加密算法领域,单钥密码体制占据了举足轻重的地位。这种体制下,信息发送方和接收方共享同一把密钥进行加密和解密,特点是...
- **接收加密报文处理方式**:对接收到的加密报文进行解密和校验。 #### 六、参数类型定义 - **PayRequest**:包含订单ID、金额、商品描述等必要信息。 - **PayResponse**:返回支付状态、交易流水号等重要信息。...