工做中須要和HPH對接,接口一些敏感信息,討論後用3DES加密,因爲我作的android郵件客戶端是依附於php系統,因此我寫加密算法對接HPH的加密,而後遇到一個棘手的問題,個人加密解密過程順利,可是一樣的密鑰,一樣的明文,java和php加密不同,後來發現雙方理解有誤我理解的密鑰是byte[]類型的,對方的密鑰是經過相似String.getBytes()的方法出來的引此爲戒php
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[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))); } }