网上的demo一搜一大堆,但是,基本上都是一知半解(包括我)。为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DES 加密和java DES加密的程序不能互通。就是加密的结果不一样,更不要说Android平台的加密输入作为java DES的解密输出了。这样的话,客户端和服务器端就不能进行通信了。我网上之前也发帖子问了不少人,但是回答都不满意。

今天部门的另外一个同事跟我说了一下,才解决了这个不能互通的问题。

调用DES加密算法包最精要的就是下面两句话:

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

CBC是工作模式,DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种模式,

PKCS5Padding是填充模式,还有其它的填充模式:

然后,cipher.init()一共有三个参数:Cipher.ENCRYPT_MODE, key, zeroIv,zeroIv就是初始化向量,一个8为字符数组。

工作模式、填充模式、初始化向量这三种因素一个都不能少。否则,如果你不指定的话,那么就要程序就要调用默认实现。问题就来了,这就与平台有关了。难怪网上一搜"DES加密结果不一致“,出现n多网页结果。(之前我并没有指定IV,被折磨了2周)

源程序如下(从java平台到android平台,我根本没有更改一行代码):

另外,一般情况下,加密后的结果都会用base64编码进行传输。

java平台:

主程序

public class testDES {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String key = "12345678";
String text = "12345678";
String result1 = DES.encryptDES(text,key);
String result2 = DES.decryptDES(result1, key);
System.out.println(result1);
System.out.println(result2);
}
}

用到的DES加密类

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class DES {
private static byte[] iv = {1,2,3,4,5,6,7,8};
public static String encryptDES(String encryptString, String encryptKey) throws Exception {
//      IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
IvParameterSpec zeroIv = new IvParameterSpec(iv);
SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
return Base64.encode(encryptedData);
}
public static String decryptDES(String decryptString, String decryptKey) throws Exception {
byte[] byteMi = new Base64().decode(decryptString);
IvParameterSpec zeroIv = new IvParameterSpec(iv);
//      IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
byte decryptedData[] = cipher.doFinal(byteMi);
return new String(decryptedData);
}
}

用到的BASE64工具类:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Base64 {
private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
/**
* data[]进行编码
* @param data
* @return
*/
public static String encode(byte[] data) {
int start = 0;
int len = data.length;
StringBuffer buf = new StringBuffer(data.length * 3 / 2);
int end = len - 3;
int i = start;
int n = 0;
while (i <= end) {
int d = ((((int) data[i]) & 0x0ff) << 16)
| ((((int) data[i + 1]) & 0x0ff) << 8)
| (((int) data[i + 2]) & 0x0ff);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append(legalChars[d & 63]);
i += 3;
if (n++ >= 14) {
n = 0;
buf.append(" ");
}
}
if (i == start + len - 2) {
int d = ((((int) data[i]) & 0x0ff) << 16)
| ((((int) data[i + 1]) & 255) << 8);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append("=");
} else if (i == start + len - 1) {
int d = (((int) data[i]) & 0x0ff) << 16;
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append("==");
}
return buf.toString();
}
private static int decode(char c) {
if (c >= 'A' && c <= 'Z')
return ((int) c) - 65;
else if (c >= 'a' && c <= 'z')
return ((int) c) - 97 + 26;
else if (c >= '0' && c <= '9')
return ((int) c) - 48 + 26 + 26;
else
switch (c) {
case '+':
return 62;
case '/':
return 63;
case '=':
return 0;
default:
throw new RuntimeException("unexpected code: " + c);
}
}
/**
* Decodes the given Base64 encoded String to a new byte array. The byte
* array holding the decoded data is returned.
*/
public static byte[] decode(String s) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
decode(s, bos);
} catch (IOException e) {
throw new RuntimeException();
}
byte[] decodedBytes = bos.toByteArray();
try {
bos.close();
bos = null;
} catch (IOException ex) {
System.err.println("Error while decoding BASE64: " + ex.toString());
}
return decodedBytes;
}
private static void decode(String s, OutputStream os) throws IOException {
int i = 0;
int len = s.length();
while (true) {
while (i < len && s.charAt(i) <= ' ')
i++;
if (i == len)
break;
int tri = (decode(s.charAt(i)) << 18)
+ (decode(s.charAt(i + 1)) << 12)
+ (decode(s.charAt(i + 2)) << 6)
+ (decode(s.charAt(i + 3)));
os.write((tri >> 16) & 255);
if (s.charAt(i + 2) == '=')
break;
os.write((tri >> 8) & 255);
if (s.charAt(i + 3) == '=')
break;
os.write(tri & 255);
i += 4;
}
}
}

adnroid平台的主函数:

public class main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String key = "12345678";
String text = "12345678";
try {
String result1 = DES.encryptDES(text,key);
String result2 = DES.decryptDES(result1, key);
Log.i("DES encode text is ", result1);
Log.i("DES encode text is ", result2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

通过查看log日志就可以看到结果。

两个平台的结果是一样的,都是:

加密结果:X2p9Uo45Tzk6Ntu6W7Ev+Q==
解密结果:12345678

最近做项目,需要加密Android客户端的一些sql语句,我当时使用的是DES加密的,结果加密出现了
1.javax.crypto.BadPaddingException: Given final block not properly padded 
这样的错误,要不就是出现乱码的问题,很纠结!当时查了一些资料,就有可能是密钥的问题或者编码的问题,检查了发现,密钥正确的,就是在创建Key 的时候,得到的byte[]数组有一些处理的,具体完整的代码如下:

1.package com.spring.sky.util;  
2.  
3.import java.io.BufferedReader;  
4.import java.io.BufferedWriter;  
5.import java.io.FileInputStream;  
6.import java.io.FileNotFoundException;  
7.import java.io.FileOutputStream;  
8.import java.io.IOException;  
9.import java.io.InputStream;  
10.import java.io.InputStreamReader;  
11.import java.io.OutputStream;  
12.import java.security.Key;  
13.  
14.import javax.crypto.Cipher;  
15.import javax.crypto.CipherInputStream;  
16.import javax.crypto.spec.SecretKeySpec;  
17.  
18.import org.apache.http.entity.InputStreamEntity;  
19.  
20./*** 
21. * DES文件加密&解密  <br> 
22. * 可以实现android和window的文件互通  
23. * @author spring.sky 
24. * Email:vipa1888@163.com 
25. * QQ:840950105 
26. * 
27. */  
28.public class FileDES {  
29.    /**加密解密的key*/  
30.    private Key mKey;  
31.    /**解密的密码*/  
32.    private Cipher mDecryptCipher;  
33.    /**加密的密码*/  
34.    private Cipher mEncryptCipher;  
35.    public FileDES(String key) throws Exception  
36.    {  
37.        initKey(key);  
38.        initCipher();  
39.    }  
40.      
41.    /** 
42.     * 创建一个加密解密的key 
43.     * @param keyRule  
44.     */  
45.    public void initKey(String keyRule) {  
46.        byte[] keyByte = keyRule.getBytes();  
47.        // 创建一个空的八位数组,默认情况下为0   
48.        byte[] byteTemp = new byte[8];  
49.        // 将用户指定的规则转换成八位数组   
50.        for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {  
51.            byteTemp[i] = keyByte[i];  
52.        }  
53.        mKey = new SecretKeySpec(byteTemp, "DES");  
54.    }  
55.      
56.    /*** 
57.     * 初始化加载密码 
58.     * @throws Exception 
59.     */  
60.    private void initCipher() throws Exception  
61.    {  
62.        mEncryptCipher = Cipher.getInstance("DES");  
63.        mEncryptCipher.init(Cipher.ENCRYPT_MODE, mKey);  
64.          
65.        mDecryptCipher = Cipher.getInstance("DES");  
66.        mDecryptCipher.init(Cipher.DECRYPT_MODE, mKey);  
67.    }  
68.      
69.    /** 
70.     * 加密文件 
71.     * @param in 
72.     * @param savePath 加密后保存的位置 
73.     */  
74.    public void doEncryptFile(InputStream in,String savePath)  
75.    {  
76.        if(in==null)  
77.        {  
78.            System.out.println("inputstream is null");  
79.            return;  
80.        }  
81.        try {  
82.            CipherInputStream cin = new CipherInputStream(in, mEncryptCipher);  
83.            OutputStream os = new FileOutputStream(savePath);  
84.            byte[] bytes = new byte[1024];  
85.            int len = -1;  
86.            while((len=cin.read(bytes))>0)  
87.            {  
88.                os.write(bytes, 0, len);  
89.                os.flush();  
90.            }  
91.            os.close();  
92.            cin.close();  
93.            in.close();  
94.            System.out.println("加密成功");  
95.        } catch (Exception e) {  
96.            System.out.println("加密失败");  
97.            e.printStackTrace();  
98.        }  
99.    }  
100.      
101.    /** 
102.     * 加密文件 
103.     * @param filePath 需要加密的文件路径 
104.     * @param savePath 加密后保存的位置 
105.     * @throws FileNotFoundException  
106.     */  
107.    public void doEncryptFile(String filePath,String savePath) throws FileNotFoundException  
108.    {  
109.        doEncryptFile(new FileInputStream(filePath), savePath);  
110.    }  
111.      
112.      
113.    /** 
114.     * 解密文件 
115.     * @param in 
116.     */  
117.    public void doDecryptFile(InputStream in)  
118.    {  
119.        if(in==null)  
120.        {  
121.            System.out.println("inputstream is null");  
122.            return;  
123.        }  
124.        try {  
125.            CipherInputStream cin = new CipherInputStream(in, mDecryptCipher);  
126.            BufferedReader reader = new BufferedReader(new InputStreamReader(cin)) ;  
127.            String line = null;  
128.            while((line=reader.readLine())!=null)  
129.            {  
130.                System.out.println(line);  
131.            }  
132.            reader.close();  
133.            cin.close();  
134.            in.close();  
135.            System.out.println("解密成功");  
136.        } catch (Exception e) {  
137.            System.out.println("解密失败");  
138.            e.printStackTrace();  
139.        }  
140.    }  
141.    /** 
142.     * 解密文件 
143.     * @param filePath  文件路径 
144.     * @throws Exception 
145.     */  
146.    public void doDecryptFile(String filePath) throws Exception  
147.    {  
148.        doDecryptFile(new FileInputStream(filePath));  
149.    }  
150.      
151.      
152.    public static void main(String[] args)throws Exception {  
153.        FileDES fileDES = new FileDES("spring.sky");  
154.        fileDES.doEncryptFile("d:/a.txt", "d:/b");  //加密   
155.        fileDES.doDecryptFile("d:/b"); //解密   
156.    }  
157.      
158.} 
上面的代码,我分别在android 1.6和java平台上面测试通过了,没任何问题的,只是根据不同的需求做一下封装,希望对大家有帮忙,让大家少走弯路!

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2012-05/60017.htm

Android DES加密解密相关推荐

  1. Android平台和java平台 DES加密解密互通程序及其不能互通的原因

    为什么80%的码农都做不了架构师?>>>    网上的demo一搜一大堆,但是,基本上都是一知半解(包括我).为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DE ...

  2. Android RSA加密解密的 工具类的使用

    RSA 比较特殊,我们首先要生成私钥和公钥,然后在加密的时候,使用私钥加密,在解密的时候使用公钥解密. //RSA 的初始化,获得私钥和密钥public void rsaInit(){try {Key ...

  3. Java实现DES加密解密

    DES(Data Encryption Standard)是一种对称加密算法,所谓对称加密就是加密和解密都是使用同一个密钥. 加密原理: DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位, ...

  4. Java简单实现DES加密解密算法

    Java简单实现DES加密解密算法 文章目录 Java简单实现DES加密解密算法 DES算法介绍 实现相关java类 代码实现 DES算法介绍 DEC加密算法属于对称加密,即利用指定的密钥,按照密码的 ...

  5. getcoo php_PHP简单实现DES加密解密的方法

    本文实例讲述了PHP简单实现DES加密解密的方法.分享给大家供大家参考,具体如下: des加密: function des_encrypt($str, $key) { $block = mcrypt_ ...

  6. .net实现md5加密 sha1加密 sha256加密 sha384加密 sha512加密 des加密解密

    写项目时,后台一直用md5加密,一天群里人问,除了MD5还有其它的加密方法吗?当时只知道还有个SHA,但怎么实现什么的都不清楚,于是当网上找了下,把几种常见的加密方法都整理了下,用winform写了个 ...

  7. python des解密_python实现DES加密解密方法实例详解

    本文实例讲述了python实现DES加密解密方法.分享给大家供大家参考.具体分析如下: 实现功能:加密中文等字符串 密钥与明文可以不等长 这里只贴代码,加密过程可以自己百度,此处python代码没有优 ...

  8. java 实现 DES加密 解密算法

    DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...

  9. DES加密解密算法Java实现

    DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半.使用子密钥对其中一半应 ...

  10. DES加密解密与AES加密解密

    × 目录 [1]AES加密算法和DES加密算法的效率比较 [2]AES和DES加密解密代码 随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了 ...

最新文章

  1. 原创jQuery移动设备弹出框插件——msgalert.js
  2. [转]Java加密算法
  3. C++之字节对齐与结构体大小
  4. Maverick.Net介绍 (来自http://www.cnblogs.com/RicCC/archive/2006/09/17/506890.html)
  5. mysql表空间界限_MySQL5.7 import表结构报错超出表空间界限
  6. 云原生和ServiceMesh主要组件--理解K8s/Istio/Envoy
  7. 大团圆结局!苹果高通和解:双方撤销全球所有诉讼
  8. Oracle连接数据库的方式
  9. JAVA IO - 高效读取大文件的后几行
  10. C++语言定义的标准转换
  11. MongoDB 的设计模式策略
  12. 蘑菇街基于Docker的私有云实践
  13. python数独解题器_python-2.7 – 数独生成器
  14. HTML三种对密码加密的方法
  15. 最全可编辑世界地图中国地图素材
  16. AspNetPager组件
  17. Maya---2018up4 Python 开发环境配置(win10x64)
  18. PXE + KS 实现系统自动部署系统
  19. Google开源C++单元测试框架gTest 5:死亡测试
  20. halcon例程学习笔记(11) 一维码、二维码识别

热门文章

  1. 网站运营手册_分享几款运营必备软件合集,欢迎补充
  2. lua 函数 默认值_简明lua教程
  3. sql like N#39;%%#39;,N 是代表什么意思 及Like语句详解
  4. 安庆集团-冲刺日志(第八天)
  5. 50个最新TypeScript面试题合集 – TypeScript开发教程
  6. 胡晓曼:MindSpore 开源运营与治理 | DEV. Together 2021 中国开发者生态峰会
  7. 项目管理知识体系指南 (六)
  8. Android获取手机存储空间大小
  9. Mac-记录一些超好用的快捷键
  10. 微信小程序tab页面切换