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

}

}

android加密DESede/CBC/PKCS5Padding的更多相关文章

  1. 关于DES加密中的 DESede/CBC/PKCS5Padding

    今天看到一段3DES加密算法的代码,用的参数是DESede/CBC/PKCS5Padding,感觉比较陌生,于是学习了一下. 遇到的java代码如下: Cipher cipher=Cipher.get ...

  2. java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/CBC/PKCS5Padding

    最近在做3DES加密,在本地window下面运行ok的程序,放到linux环境上竟然报错: Java.security.NoSuchAlgorithmException: Cannot find an ...

  3. nodejs版本DESede/CBC/PKCS5Padding算法封装(3des)

    最近对接了一个第三方支付项目,用的加密算法是根本没听过的:DESede/CBC/PKCS5Padding 这个算法真的是坑爹了,网上搜索了一堆只有java版本是正常的,nodejs版本的各种问题,我了 ...

  4. DESede/CBC/PKCS5Padding

    Java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/CBC/PKCS5Padding ...

  5. Android DES加密的CBC模式加密解密和ECB模式加密解密

    DES加密共有四种模式:电子密码本模式(ECB).加密分组链接模式(CBC).加密反馈模式(CFB)和输出反馈模式(OFB). CBC模式加密: import java.security.Key; i ...

  6. C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式

    ============================================== des   cbc  加密 zeropadding填充方式 ======================= ...

  7. php实现AES/CBC/PKCS5Padding加密解密(又叫:对称加密)

    今天在做一个和java程序接口的架接,java那边需要我这边(PHP)对传过去的值进行AES对称加密,接口返回的结果也是加密过的(就要用到解密),然后试了很多办法,也一一对应了AES的key密钥值,偏 ...

  8. AES/CBC/PKCS5Padding对称加密

    package unit; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.cry ...

  9. OC的DES加密,使与java的Cipher类用DES/CBC/PKCS5Padding方式的加密结果同样

    问题说明: 近期用到DES加密,而且要与java的Cipher类加密的结果保持一致.没研究过java的Cliper,但工作中Cipher依据DES/CBC/PKCS5Padding加密方式生成了一个字 ...

随机推荐

  1. AudioEffect中文API

    在Android2.3中增加了对音频混响的支持,这些API包含在android.media.audiofx包中. 一.概述 AudioEffect是android audio framework(an ...

  2. java Set(集合)

    set不保存重复的元素(至于如何判断元素相同则较为复杂,后面将会看到).Set中最常被使用的是测试归属表,你可以很容易地询问某个对象是否在某个Set中,正因如此,查找就成了Set最重要的操作,因此通常 ...

  3. 003_Java笔记3:Eclipse添加jar包

    本文以jedis包为例,演示Eclipse如何添加和使用jar包.   1 建立一个名为ImportJarDemo的Java Project.在该工程下建立一个libs的文件夹. 2 将下载的jedi ...

  4. Net WebAPI2

    SwaggerUI ASP.Net WebAPI2   目前在用ASP.NET的 WebAPI2来做后台接口开发,在与前台做测试的时候,总是需要发送一个demo给他,但是这样很麻烦的,他还有可能记不住 ...

  5. 【LOJ】#2110. 「JLOI2015」管道连接

    题解 我们先跑一个斯坦纳树出来 斯坦纳树是什么,是一个包含点集里的点联通所需要的最小的价值,显然他们联通的方式必然是一棵树 我们可以设一个状态为\(dis[i][S]\)表示以第i个点为根,点集为\( ...

  6. 开始使用KVM和QEMU

    一. 简介 Quick Emulator(QEMU) 是QEMU/KVM虚拟化套件中的主要组成部分. 它提供了硬件的虚拟化和处理器的仿真. QEMU不用运行在内核,它是运行在用户空间的. QEMU支持 ...

  7. Maximum Shortest Distance 最大团 二分答案 HDU 3585

    题意:给出n个点   要求取k个点  这k个点中  距离最小的两个点要求距离最大 拿到手看不出是最大团  也看不出是二分答案(第一次用) 因为答案必然存在 一定有一个最值  所以用二分答案来做 最大距 ...

  8. 移动端h5需要注意的一些事

    1.移动端点击a标签出现的背景色 a, a:hover, a:active, a:visited, a:link, a:focus { -webkit-tap-highlight-color: rgb ...

  9. 浅析Entity FrameWork性能优化

    浅析EF性能优化 1.       数据Load 延迟加载:当实体第一次读取时,相关数据没有加载:当第一次试图访问导航属性时,所需的导航数据自动加载,EF默认使用这种方式加载数据,尽量使用预先加载和显 ...

  10. IEnumerable<T>

    IEnumerable 饮水思源 <C#本质论> Overview 根据定义,.Net 的中集合,本质上是一个类,它最起码实现了IEnumeraable 或者非泛型的IEnumerable ...