查看: 1548|回复: 0
打印 上一主题 下一主题

android加密DESede/CBC/PKCS5Padding

[复制链接]
跳转到指定楼层
沙发
发表于 2015-4-12 15:25:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

工作中需要和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[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 & 0xff) < 16)
                buf.append("0");
            buf.append(Long.toString(bytes & 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);
            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)));

    }

}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表