android加密DESede/CBC/PKCS5Padding
from://http://my.oschina.net/u/269082/blog/56163
工作中需要和HPH对接,接口一些敏感信息,讨论后用3DES加密,由于我做的android邮件客户端是依附于php系统,所以我写加密算法对接HPH的加密,然后遇到一个棘手的问题,我的加密解密过程顺利,但是同样的密钥,同样的明文,java和php加密不一样,后来发现双方理解有误我理解的密钥是byte[]类型的,对方的密钥是通过类似String.getBytes()的方法出来的引此为戒
import java.security.SecureRandom;
import
java.security.Security;
import
java.util.Random;
import
javax.crypto.Cipher;
import
javax.crypto.KeyGenerator;
import
javax.crypto.SecretKey;
import
javax.crypto.SecretKeyFactory;
import
javax.crypto.spec.DESedeKeySpec;
import
javax.crypto.spec.IvParameterSpec;
import
javax.crypto.spec.SecretKeySpec;
/*字符串 DESede(3DES)
加密*/
public class ThreeDes
{
/**
*
3DS加密
*
* @author [email protected]
*/
private static final
String Algorithm = "DESede/CBC/PKCS5Padding"; //
定义加密算法,可用
//
DES,DESede,Blowfish,DESede/CBC/PKCS5Padding
// keybyte为加密密钥,长度为24字节
//
src为被加密的数据缓冲区(源)
/*
* private static SecretKey
deskey = null;
*
* public static void
getKey(byte[] strKey) { try { KeyGenerator
_generator
* =
KeyGenerator.getInstance("DES");
_generator.init(new
*
SecureRandom(strKey)); deskey = _generator.generateKey(); _generator
=
* null; } catch (Exception e) {
e.printStackTrace(); } }
*/
public static byte[]
encryptMode(String iv, String key, String src)
{
try
{
byte[] keybyte = key.getBytes();
byte[] rand = new
byte[8];
rand =
iv.getBytes();
// 用随即数生成初始向量
/*
* Random r=new Random();
r.nextBytes(rand);
*/
IvParameterSpec ivp = new
IvParameterSpec(rand);
//
生成密钥
// SecureRandom sr = new
SecureRandom();
DESedeKeySpec dks = new
DESedeKeySpec(keybyte);
SecretKeyFactory keyFactory =
SecretKeyFactory
.getInstance("DESede");
SecretKey securekey =
keyFactory.generateSecret(dks);
// IvParameterSpec iv = new
IvParameterSpec(PASSWORD_IV.getBytes());
/*
* Cipher cipher =
Cipher.getInstance("DESede");
* cipher.init(Cipher.ENCRYPT_MODE,
securekey, ivp, sr); return new
*
String(Hex.encodeHex(cipher.doFinal(str.getBytes())));
*/
// 加密
Cipher c1 =
Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE, securekey,
ivp);
return c1.doFinal(src.getBytes());//
在单一方面的加密或解密
}
catch (java.security.NoSuchAlgorithmException e1)
{
// TODO: handle
exception
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(String iv, String key, byte[] src)
{
try
{
byte[] srcbytes = src;
byte[] keybyte =
key.getBytes();
byte[] rand = new
byte[8];
rand =
iv.getBytes();
// 用随即数生成初始向量
/*
* Random r=new Random();
r.nextBytes(rand);
*/
IvParameterSpec ivp = new
IvParameterSpec(rand);
//
生成密钥
SecureRandom sr = new
SecureRandom();
DESedeKeySpec dks = new
DESedeKeySpec(keybyte);
SecretKeyFactory keyFactory =
SecretKeyFactory
.getInstance("DESede");
SecretKey securekey =
keyFactory.generateSecret(dks);
//
解密
Cipher c1 =
Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, securekey,
ivp);
/*
* int len = src.getBytes().length;
byte[] zero = { 0x00, 0x00,
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; if (len < 8) { srcbytes =
* new byte[8];
System.arraycopy(src.getBytes(), 0, srcbytes,
0,
* len); System.arraycopy(zero, len, srcbytes, len, 8 -
len); } else
* { srcbytes = src.getBytes();
}
*/
return
c1.doFinal(srcbytes);
} catch (java.security.NoSuchAlgorithmException e1)
{
// TODO: handle
exception
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2)
{
e2.printStackTrace();
} catch (java.lang.Exception e3)
{
e3.printStackTrace();
}
return null;
}
//
转换成十六进制字符串
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;
}
if (n < b.length -
1)
hs = hs +
":";
}
return
hs.toUpperCase();
}
public static final String
encodeHex(byte bytes[]) {
StringBuffer buf = new StringBuffer(bytes.length *
2);
for (int i = 0;
i < bytes.length; i++) {
if ((bytes[i] & 0xff) <
16)
buf.append("0");
buf.append(Long.toString(bytes[i] & 0xff,
16));
}
return
buf.toString();
}
public static final byte[]
decodeHex(String hex) {
char chars[] =
hex.toCharArray();
byte bytes[] = new byte[chars.length /
2];
int byteCount =
0;
for (int i = 0; i
< chars.length; i += 2) {
int newByte =
0;
newByte |=
hexCharToByte(chars[i]);
newByte <<=
4;
newByte |= hexCharToByte(chars[i +
1]);
bytes[byteCount] = (byte)
newByte;
byteCount++;
}
return bytes;
}
private static final byte
hexCharToByte(char ch) {
switch (ch) {
case 48: // ‘0‘
return
0;
case 49: //
‘1‘
return 1;
case 50: // ‘2‘
return
2;
case 51: //
‘3‘
return 3;
case 52: // ‘4‘
return
4;
case 53: //
‘5‘
return 5;
case 54: // ‘6‘
return
6;
case 55: //
‘7‘
return 7;
case 56: // ‘8‘
return
8;
case 57: //
‘9‘
return 9;
case 97: // ‘a‘
return
10;
case 98: //
‘b‘
return 11;
case 99: // ‘c‘
return
12;
case 100: //
‘d‘
return 13;
case 101: // ‘e‘
return
14;
case 102: //
‘f‘
return 15;
case 58: // ‘:‘
case 59: // ‘;‘
case 60: // ‘<‘
case 61: // ‘=‘
case 62: // ‘>‘
case 63: // ‘?‘
case 64: // ‘@‘
case 65: // ‘A‘
case 66: // ‘B‘
case 67: // ‘C‘
case 68: // ‘D‘
case 69: // ‘E‘
case 70: // ‘F‘
case 71: // ‘G‘
case 72: // ‘H‘
case 73: // ‘I‘
case 74: // ‘J‘
case 75: // ‘K‘
case 76: // ‘L‘
case 77: // ‘M‘
case 78: // ‘N‘
case 79: // ‘O‘
case 80: // ‘P‘
case 81: // ‘Q‘
case 82: // ‘R‘
case 83: // ‘S‘
case 84: // ‘T‘
case 85: // ‘U‘
case 86: // ‘V‘
case 87: // ‘W‘
case 88: // ‘X‘
case 89: // ‘Y‘
case 90: // ‘Z‘
case 91: // ‘[‘
case 92: // ‘\\‘
case 93: // ‘]‘
case 94: // ‘^‘
case 95: // ‘_‘
case 96: // ‘`‘
default:
return
0;
}
}
public static void main(String[]
args) {
// TODO
Auto-generated method stub
//
添加新安全算法,如果用JCE就要把它添加进去
// Security.addProvider(new
com.sun.crypto.provider.SunJCE());
/*
* final byte[] keyBytes = { 0x01, 0x02, 0x03,
0x04,
*
*
(byte) 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x01,
0x02,
*
*
(byte) 0x03,
*
*
(byte) 0x04, 0x05, 0x06, 0x07, 0x08,
0x09,
*
*
(byte) 0x00, 0x01, 0x02, 0x03,
*
* (byte) 0x04
*
* }; //
24字节的密钥
*/
String
szSrc = "1";
System.out.println("加密前的字符串:" +
szSrc);
byte[]
encoded = encryptMode("12345678",
"123456789012345678943210",
szSrc);
System.out.println("加密后的字符串:" +
encodeHex(encoded));
byte[] srcBytes = decryptMode("12345678",
"123456789012345678943210",
"c5e8faaf1a0e52ae".getBytes());
System.out.println("解密后的字符串:" + (new
String(srcBytes)));
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。