`
hejiajunsh
  • 浏览: 408936 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

Java实现与.net对应的3DES加密解密

阅读更多

.net的3DES加密解密代码:

public static string TripleDESDecrypt(string pToDecrypt, string sKey)
        {
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.Zeros;
            byte[] inputByteArray = new byte[pToDecrypt.Length / 2]; // pToDecrypt.Length / 2 = 8
            for (int x = 0; x < pToDecrypt.Length / 2; x++) // pToDecrypt.Length = 16
            {
                string s = pToDecrypt.Substring(x * 2, 2);
                int i = (Convert.ToInt32(s, 16));
                inputByteArray[x] = (byte)i;
            }

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); // {byte[24]}
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            return System.Text.Encoding.Default.GetString(ms.ToArray());
        }

        public static string TripleDESEncrypt(string pToEncrypt, string sKey)   // 加密
        {
            try {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.Zeros;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock(); ;
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray()) {
                    ret.AppendFormat("{0:X2}", b);
                }
                ret.ToString();
                return ret.ToString();
            } catch (Exception ex) {
                return ex.Message;
            }
        } 

 

现在把上面的代码用java实现,要求加解密后的内容与.net一致.

使用cipher可以很容易的实现3des加密,但是跟其他平台开发的3des加密对接来说,通常会有一些问题。基本程序如下:

   public static byte[] desEncrypt(String message, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("DESede");

        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(message.getBytes("UTF-8"));
  }

 

 与其他平台对接发现对同样输入加密以后结果不同,看看jdk的文档,有如下描述:

transformation is a string that describes the operation (or set of operations) to be performed on the given input, to produce some output.

A transformation is of the form:

 

  • "algorithm/mode/padding" or 
  • "algorithm"

根据前面的代码,我们已经选择了正确的算法,那么加密不同的原因应该就是mode和padding了。

he SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. This means that in the case of the SunJCE provider, 
    Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");
and 
    Cipher c1 = Cipher.getInstance("DES");
are equivalent statements.

对于其他语言开发的3des,一定要采用相同的mode和padding才能保证通信。

Appendix A of this document contains a list of standard names that can be used to specify the algorithm name, mode, and padding scheme components of a transformation.(Appendix A 此链接规定了java加密算法的 名称/加密运算模式/填充模式,可参考.)

 

从上面.net的代码可以看出,

des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); // 加密密匙
des.Mode = CipherMode.ECB; // 运算模式
des.Padding = PaddingMode.Zeros; //填充模式

 

因此,对应的java代码应该为:

Security.addProvider(new com.sun.crypto.provider.SunJCE());
SecretKey desKey = new SecretKeySpec("your key".getBytes("utf-8"), ALGORITHM_KEY);
Cipher tcipher = Cipher.getInstance("DESede/ECB/NoPadding");
tcipher.init(Cipher.DECRYPT_MODE, desKey);

 

完整的代码如下:

import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Properties;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class TripleDesUtils {
	private static final String ALGORITHM_KEY = "DESede";
	private static final String ALGORITHM_CIPHER_INIT = "DESede/ECB/NoPadding";

	/**
	 * 字节数组转化为大写16进制字符串
	 *
	 * @param b
	 * @return
	 */
	private 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();
	}

	public static void main(String[] args) throws Exception {
		Properties pro = PropertiesUtils.getProperties("3des.properties");
		String algorithm_key = pro.getProperty("3des_algorithm_key");
		TripleDesUtils t = new TripleDesUtils();
		t.key = algorithm_key;

		System.out.println("加密后的:" + t.encrypt_ECB("2014-5-7"));
		System.out.println("解密后的:" + t.decrypt_ECB("50E09194AB312A08").trim());
	}


	/**
	 * 字符串转字节数组
	 *
	 * @param s
	 * @return
	 */
	private static byte[] str2ByteArray(String s) {
		int byteArrayLength = s.length() / 2;
		byte[] b = new byte[byteArrayLength];
		for (int i = 0; i < byteArrayLength; i++) {
			byte b0 = (byte) Integer.valueOf(s.substring(i * 2, i * 2 + 2), 16).intValue();
			b[i] = b0;
		}
		return b;
	}

	private Cipher cipher = null;

	// 密钥
	private String key = "";

	private byte[] decrypt_ECB(byte[] src) {
			cipher = initCipher(Cipher.DECRYPT_MODE);
			try {
				return cipher.doFinal(src);
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
			}
			return null;
	}

	public String decrypt_ECB(String src) {
		byte[] b = decrypt_ECB(str2ByteArray(src));
		return new String(b);
	}

	private byte[] encrypt_ECB(byte[] src) {
		try {
			cipher = initCipher(Cipher.ENCRYPT_MODE);
			return cipher.doFinal(src);
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public String encrypt_ECB(String src) {
		byte[] b;
		try {
			b = encrypt_ECB(src.getBytes("utf-8"));
			return byte2Hex(b);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public String getKey() {
		return key;
	}

	private final Cipher initCipher(int mode) {
		try {
			Security.addProvider(new com.sun.crypto.provider.SunJCE());
//			Security.addProvider(new BouncyCastleProvider());
			SecretKey desKey = new SecretKeySpec(key.getBytes("utf-8"), ALGORITHM_KEY);
			Cipher tcipher = Cipher.getInstance(ALGORITHM_CIPHER_INIT);
			tcipher.init(mode, desKey);
			return tcipher;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void setKey(String key) {
		this.key = key;
	}
}

 

分享到:
评论

相关推荐

    android端写的DES加密解密代码对应C#写的加密解密代码。两者加密解密结果完全一致

    本文将深入探讨Android端与C#端的DES加密解密实现,以及如何确保它们之间的兼容性。 首先,DES是一种块加密算法,使用64位的数据块和56位的密钥进行操作。它的加密过程分为一系列的替换和转换步骤,通过这些步骤将...

    Java加密与解密的艺术配书源代码源码整理

    源代码整理部分,`javaSrc175.zip`可能包含了与书中各个章节对应的示例代码,这些代码可以帮助读者更直观地理解和实现上述加密解密技术。下载并解压后,按照`下载及使用说明.txt`的指示,可以浏览和运行代码,加深对...

    C#.NET各种解密方法,请求方法

    关于解密和加密,C#.NET提供了多种算法实现,如AES、DES、3DES、RSA等。`System.Security.Cryptography`命名空间提供了对应的类,如`AesManaged`用于AES加密,`RSACryptoServiceProvider`用于RSA加密。在实际应用中...

    对称加密适用java和net

    压缩包内的文件"DES.cs"很可能是一个.NET实现的DES加密类,而"QCDES.java"可能是Java实现的类,它们都可能是为了在两个平台上进行对称加密通信而设计的。 为了在Java和.NET之间实现跨平台的数据加密传输,你需要...

    Java加密与解密的艺术

    在学习"Java加密与解密的艺术"时,你将深入到加密算法的细节,学习如何在Java中实现这些算法,以及如何结合实际需求构建安全的加密系统。通过阅读提供的PDF文档,你将有机会掌握这些技能,为你的系统构建一道坚实的...

    DES CBC模式加密

    JavaScript实现的DES CBC加密算法可以与后端的Java或.NET环境下的DES加密算法兼容,这是因为它们遵循了相同的加密标准和模式。在JavaScript中,可以使用开源库如crypto-js来实现DES CBC加密。这个库提供了加密和解密...

    MD5算法,URLEncoding,Base64编码,AES,DES,DESede,RSA加密解密工具类和使用实例

    例如,使用`java.security.MessageDigest`实现MD5计算,`java.net.URLEncoder`进行URL编码,`java.util.Base64`处理Base64编码,以及使用`javax.crypto.Cipher`进行AES、DES、DESede和RSA的加解密操作。 总的来说,...

    Java文件加解密工具

    在Java中,我们可以使用javax.crypto包中的类来实现AES和DES加密,如 Cipher 类用于加密和解密操作,KeyGenerator 用于生成密钥。 非对称加密则使用一对公钥和私钥,一个用于加密,另一个用于解密。RSA算法就是一种...

    java实现的8583发包解包

    在Java中,可以使用`java.net.Socket`和`java.net.ServerSocket`类进行客户端和服务器端的通信。在8583报文的发送和接收过程中,通常会在一个线程中创建ServerSocket监听客户端连接,另一个线程处理接收到的数据。...

    AES报文加密1

    本篇将重点讲解AES加密、对称与非对称加密的区别以及如何在Java、.NET和PHP中实现AES加密。 AES是一种块密码,其基本工作模式是将明文数据分成128位的块进行加密,密钥长度可以是128、192或256位。在本例中,我们...

    org.bouncycastle 加密算法包 最新1.69版

    对称加密是使用同一密钥进行加密和解密的方法,如 DES(Data Encryption Standard)、3DES、AES(Advanced Encryption Standard)等。Bouncy Castle 提供了这些算法的实现,允许开发者在应用中方便地集成数据保护。...

    Java实用程序设计100例(7)

    Java的`javax.crypto.Cipher`类用于实现加密和解密操作。常见的对称加密算法有AES、DES等。首先,我们需要创建一个`Cipher`实例,然后使用`init()`方法初始化它,接着调用`doFinal()`执行加密或解密。 **实例86:非...

    bcprov-jdk16-146.jar

    在不同的Java版本中,bcprov会有对应的版本,以确保与特定Java版本的兼容性。1.6版本的Java在2009年发布,对于那些仍运行在Java 1.6环境的应用来说,bcprov-jdk16-146.jar是理想的加密库选择。 "146"是这个特定版本...

    bouncycastle jar包

    Bouncy Castle 提供了许多实用工具,如证书和证书请求的创建、解析和管理,密钥对生成器,加密解密工具,以及对PKCS#7、PKCS#12、OpenPGP等标准的支持。 ### 文件名解析 由于提供的文件名`fda881e5d7e247438c52f9...

    BouncyCastle.Crypto 1.8.1动态库dll

    - **加密与解密**:根据选择的加密算法,调用对应的加密和解密方法,如`CryptoStream`和`ICryptoTransform`接口,处理数据流。 - **签名与验证**:使用私钥进行数字签名,公钥验证签名,确保数据未被篡改。 - **...

    BouncyCastle:弹跳城堡的简单用法

    BouncyCastle的`PBEWithMD5AndDES`或`PBEWithSHA1AndDESede`类可以实现DES加密解密,通常结合口令为基础的加密(PBE)增强安全性。 4. **AES加密与解密** AES(Advanced Encryption Standard)是现代对称加密的标准...

Global site tag (gtag.js) - Google Analytics