您的位置:首页 > 移动开发 > Android开发

android加密DESede/CBC/PKCS5Padding

2013-11-14 19:31 399 查看
工作中需要和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 liyunlong_88@126.com

*/

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
& 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)));

}

}

【原文:/article/3466334.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: