Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .
来源:互联网 发布:图文直播软件下载 编辑:程序博客网 时间:2024/04/30 11:38
网上的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平台:
主程序
01
public
class
testDES {
02
03
/**
04
* @param args
05
* @throws Exception
06
*/
07
public
static
void
main(String[] args)
throws
Exception {
08
// TODO Auto-generated method stub
09
String key =
"12345678"
;
10
String text =
"12345678"
;
11
String result1 = DES.encryptDES(text,key);
12
String result2 = DES.decryptDES(result1, key);
13
System.out.println(result1);
14
System.out.println(result2);
15
}
16
}
01
import
javax.crypto.Cipher;
02
import
javax.crypto.spec.IvParameterSpec;
03
import
javax.crypto.spec.SecretKeySpec;
04
05
public
class
DES {
06
private
static
byte
[] iv = {
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
};
07
public
static
String encryptDES(String encryptString, String encryptKey)
throws
Exception {
08
// IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
09
IvParameterSpec zeroIv =
new
IvParameterSpec(iv);
10
SecretKeySpec key =
new
SecretKeySpec(encryptKey.getBytes(),
"DES"
);
11
Cipher cipher = Cipher.getInstance(
"DES/CBC/PKCS5Padding"
);
12
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
13
byte
[] encryptedData = cipher.doFinal(encryptString.getBytes());
14
15
return
Base64.encode(encryptedData);
16
}
17
public
static
String decryptDES(String decryptString, String decryptKey)
throws
Exception {
18
byte
[] byteMi =
new
Base64().decode(decryptString);
19
IvParameterSpec zeroIv =
new
IvParameterSpec(iv);
20
// IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
21
SecretKeySpec key =
new
SecretKeySpec(decryptKey.getBytes(),
"DES"
);
22
Cipher cipher = Cipher.getInstance(
"DES/CBC/PKCS5Padding"
);
23
cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
24
byte
decryptedData[] = cipher.doFinal(byteMi);
25
26
return
new
String(decryptedData);
27
}
28
}
001
import
java.io.ByteArrayOutputStream;
002
import
java.io.IOException;
003
import
java.io.OutputStream;
004
005
006
007
public
class
Base64 {
008
private
static
final
char
[] legalChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
009
/**
010
* data[]进行编码
011
* @param data
012
* @return
013
*/
014
public
static
String encode(
byte
[] data) {
015
int
start =
0
;
016
int
len = data.length;
017
StringBuffer buf =
new
StringBuffer(data.length *
3
/
2
);
018
019
int
end = len -
3
;
020
int
i = start;
021
int
n =
0
;
022
023
while
(i <= end) {
024
int
d = ((((
int
) data[i]) &
0x0ff
) <<
16
)
025
| ((((
int
) data[i +
1
]) &
0x0ff
) <<
8
)
026
| (((
int
) data[i +
2
]) &
0x0ff
);
027
028
buf.append(legalChars[(d >>
18
) &
63
]);
029
buf.append(legalChars[(d >>
12
) &
63
]);
030
buf.append(legalChars[(d >>
6
) &
63
]);
031
buf.append(legalChars[d &
63
]);
032
033
i +=
3
;
034
035
if
(n++ >=
14
) {
036
n =
0
;
037
buf.append(
" "
);
038
}
039
}
040
041
if
(i == start + len -
2
) {
042
int
d = ((((
int
) data[i]) &
0x0ff
) <<
16
)
043
| ((((
int
) data[i +
1
]) &
255
) <<
8
);
044
045
buf.append(legalChars[(d >>
18
) &
63
]);
046
buf.append(legalChars[(d >>
12
) &
63
]);
047
buf.append(legalChars[(d >>
6
) &
63
]);
048
buf.append(
"="
);
049
}
else
if
(i == start + len -
1
) {
050
int
d = (((
int
) data[i]) &
0x0ff
) <<
16
;
051
052
buf.append(legalChars[(d >>
18
) &
63
]);
053
buf.append(legalChars[(d >>
12
) &
63
]);
054
buf.append(
"=="
);
055
}
056
057
return
buf.toString();
058
}
059
060
private
static
int
decode(
char
c) {
061
if
(c >=
'A'
&& c <=
'Z'
)
062
return
((
int
) c) -
65
;
063
else
if
(c >=
'a'
&& c <=
'z'
)
064
return
((
int
) c) -
97
+
26
;
065
else
if
(c >=
'0'
&& c <=
'9'
)
066
return
((
int
) c) -
48
+
26
+
26
;
067
else
068
switch
(c) {
069
case
'+'
:
070
return
62
;
071
case
'/'
:
072
return
63
;
073
case
'='
:
074
return
0
;
075
default
:
076
throw
new
RuntimeException(
"unexpected code: "
+ c);
077
}
078
}
079
080
/**
081
* Decodes the given Base64 encoded String to a new byte array. The byte
082
* array holding the decoded data is returned.
083
*/
084
085
public
static
byte
[] decode(String s) {
086
087
ByteArrayOutputStream bos =
new
ByteArrayOutputStream();
088
try
{
089
decode(s, bos);
090
}
catch
(IOException e) {
091
throw
new
RuntimeException();
092
}
093
byte
[] decodedBytes = bos.toByteArray();
094
try
{
095
bos.close();
096
bos =
null
;
097
}
catch
(IOException ex) {
098
System.err.println(
"Error while decoding BASE64: "
+ ex.toString());
099
}
100
return
decodedBytes;
101
}
102
103
private
static
void
decode(String s, OutputStream os)
throws
IOException {
104
int
i =
0
;
105
106
int
len = s.length();
107
108
while
(
true
) {
109
while
(i < len && s.charAt(i) <=
' '
)
110
i++;
111
112
if
(i == len)
113
break
;
114
115
int
tri = (decode(s.charAt(i)) <<
18
)
116
+ (decode(s.charAt(i +
1
)) <<
12
)
117
+ (decode(s.charAt(i +
2
)) <<
6
)
118
+ (decode(s.charAt(i +
3
)));
119
120
os.write((tri >>
16
) &
255
);
121
if
(s.charAt(i +
2
) ==
'='
)
122
break
;
123
os.write((tri >>
8
) &
255
);
124
if
(s.charAt(i +
3
) ==
'='
)
125
break
;
126
os.write(tri &
255
);
127
128
i +=
4
;
129
}
130
}
131
132
}
01
public
class
main
extends
Activity {
02
/** Called when the activity is first created. */
03
@Override
04
public
void
onCreate(Bundle savedInstanceState) {
05
super
.onCreate(savedInstanceState);
06
setContentView(R.layout.main);
07
08
String key =
"12345678"
;
09
String text =
"12345678"
;
10
11
12
try
{
13
String result1 = DES.encryptDES(text,key);
14
String result2 = DES.decryptDES(result1, key);
15
Log.i(
"DES encode text is "
, result1);
16
Log.i(
"DES encode text is "
, result2);
17
}
catch
(Exception e) {
18
// TODO Auto-generated catch block
19
e.printStackTrace();
20
}
21
}
22
}
两个平台的结果是一样的,都是:
加密结果:X2p9Uo45Tzk6Ntu6W7Ev+Q==
解密结果:12345678
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- 【代码】Android和java平台 DES加密解密互通程序及其不能互通的原因
- Android平台和java平台 DES、3DES、RSA加密解密互通程序及其不能互通的原因
- Java和.net加密解密互通DES
- AES加密解密在JAVA和ANDROID下互通
- AES加密解密(互通.NET和JAVA)
- Java和.net加密解密互通RSA
- DES加密解密—Android IOS C#互通
- .NET 与 Java DES 加密/解密 互通 方法
- Android 平台DES加密解密
- li元素中包含img元素出现5px空白的解决方法
- 给Android设备增加串口功能
- VC编程功能总结
- 在批处理中提升权限 (UAC开启状态下)
- 国内创业团队推爱闲置:LBS二手物品交易应用
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .
- 解决 ORA-01461: can bind a LONG value only for insert into a LONG column
- java获取项目根路径
- Intel 64 Memory ordering principles
- 地图API
- mj评-《超级战舰》-8分
- Windows环境进程间通信(三) 内存映射文件
- iOS画矩形、直线、文字的方法
- 升级内核版本后,需要重新编译一下网卡驱动