DES加密与解密


密钥

Java中两种生成密钥的方式

  • 利用已有key生成securekey
/**key(string)为已知密钥,利用密钥生成器,得到securekey**/
SecretKey securekey = null;  
if(key == null){  
    key = "";  
}  
KeyGenerator keyGenerator = KeyGenerator.getInstance(DES);  
keyGenerator.init(new SecureRandom(key.getBytes()));  
securekey = keyGenerator.generateKey();  
return securekey;  
  • 取key前8Byte作为securekey
// 生成一个可信任的随机数源
 SecureRandom sr = new SecureRandom();
// 从原始密钥数据创建DESKeySpec对象
 DESKeySpec dks = new DESKeySpec(key.getBytes());
// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
 SecretKey securekey = keyFactory.generateSecret(dks);

两种方式得到的key是不同的,对应的加密init方法。

Cipher cipher = Cipher.getInstance(DES);
cipher.init(Cipher.ENCRYPT_MODE,securekey);  //第一种
cipher.init(Cipher.ENCRYPT_MODE,securekey,sr);  //第二种

由于key的不同,加密后的内容不同

其实写这篇博客是因为C#的原因
第二种方式对于C#与Java之间的互通是很好把握的
但是第一种方式呢,C#是无法使用类似KeyGenerator这样的密钥生成器,至少我还没有找到,希望对C#比较了解的童鞋们,给点帮助,谢谢!

Java完整代码示例:

import java.io.IOException;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

 /*该示例以第二种方式得到密钥*/
public class DesUtil {

    private final static String DES = "DES";
     /*入口*/
    public static void main(String[] args) throws Exception {
        String data = "123 456";

        String key = "abcde67890";
        System.err.println(encrypt(data, key));
        System.err.println(decrypt(encrypt(data, key), key));

    }
    /*此方法作为参考,可替换加密和解密函数中的生成密钥方式,注意类型的匹配,string / byte */
    public static Key getSecretKey(String key) throws Exception{  
        SecretKey securekey = null;  
        if(key == null){  
            key = "";  
        }  
        KeyGenerator keyGenerator = KeyGenerator.getInstance(DES);  
        keyGenerator.init(new SecureRandom(key.getBytes()));  
        securekey = keyGenerator.generateKey();  
        return securekey;  
    }  

    /**
     * Description 根据键值进行加密
     * @param data 
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        byte[] bt = encrypt(data.getBytes(), key.getBytes());
        String strs = new BASE64Encoder().encode(bt);
        return strs;
    }

    /**
     * Description 根据键值进行解密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws IOException
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws IOException,Exception {
        if (data == null)
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] buf = decoder.decodeBuffer(data);
        byte[] bt = decrypt(buf,key.getBytes());
        return new String(bt);
    }

    /**
     * Description 根据键值进行加密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        Cipher cipher = Cipher.getInstance(DES);
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);// 若使用第一种方式,可去掉,sr,相应的securekey调用参考方法
        return cipher.doFinal(data);
    }

    /**
     * Description 根据键值进行解密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(key);

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance(DES);

        // 用密钥初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);//, sr
        return cipher.doFinal(data);
    }
}


Java与C#

这里就贴下C#的加密解密的示例代码
需要做一些说明

Java中DES加密默认ECB模式,C#中默认CBC模式,所以模式需要统一
C#中存在IV参数,如果是ECB模式,那么该参数也不会有所作用,所以可以忽略该值。

 public static string strEncryptDES(string encryptString, string encryptKey)
        {
            try
            {
                byte[] btKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] btIV = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                des.Mode = CipherMode.ECB;//模式
                des.Padding = PaddingMode.PKCS7;

                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = Encoding.UTF8.GetBytes(encryptString);
                    try
                    {
                        using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                        {
                            cs.Write(inData, 0, inData.Length);
                            cs.FlushFinalBlock();
                        }
                        return Convert.ToBase64String(ms.ToArray());
                    }
                    catch
                    {
                        return encryptString;
                    }
                }
            }
            catch { }
            return "DES加密出错";  
        }

        public static string strDecryptDES(string encryptedString, string encryptKey)
        {        
            byte[] btKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0,8));    
            byte[] btIV = Encoding.UTF8.GetBytes(encryptKey.Substring(0,8));  

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();  
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;

            using (MemoryStream ms = new MemoryStream())  
            {  
                byte[] inData = Convert.FromBase64String(encryptedString);  
                try  
                {  
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))  
                    {  
                        cs.Write(inData, 0, inData.Length);  

                        cs.FlushFinalBlock();  
                    }  

                    return Encoding.UTF8.GetString(ms.ToArray());  
                }  
                catch  
                {  
                    return encryptedString;  
                }  
            }  
        }

主要就是C#与Java互通的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值