昨天遇到了这个问题:Android下DES加密和J2SE平台下加密结果不一样。奇怪的是,两个平台的代码是一样的。但是结果不一样,有没有人知道这是为什么啊?Bas464编码在Android2.2平台上有现成的包,java平台上找的写的Base64编码
也和标准的sun.misc.BASE64Encoder;及其sun.misc.BASE64Decoder一样。
运行出来的结果:
Android平台上是Pf6/li3ylc0=,而j2se平台上是k1khzCqbePs=
Android中的test类代码如下:
import android.app.Activity;
import android.os.Bundle;
//import android.util.BASE64;
import android.util.Base64;
import android.util.Log;
//import com.utils.Base64;
import com.utils.DES;
import com.utils.DES1;
import com.utils.DesEncrypt;
public class test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String text = "CHINA";    
        DES1.getKey("12345678");
        String encode2 = DES1.getEncString(text);
        Log.i("DES encode text is ", encode2);    }
}用到的DES1类如下:
import java.security.Key; 
import java.security.SecureRandom; 
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; import android.util.Base64;
/**
 * all methods are static,利用android2.2自带的SDK中的BASE64编码 
 * @author randyjia
 *
 */
public class DES1 { 
private static Key key; 
/** 
* 根据参数生成KEY 
* @param strKey 
*/ 
public static void getKey(String strKey) { 
try{ 
KeyGenerator _generator = KeyGenerator.getInstance("DES"); 
_generator.init(new SecureRandom(strKey.getBytes())); 
key = _generator.generateKey(); 
System.out.println("key is " + new String(key.getEncoded(),"UTF-8"));
_generator = null; 
}catch(Exception e){ 
e.printStackTrace(); 


/** 
* 加密:  String明文输入,String密文输出 
* @param strMing 
* @return 
*/ 
public static String getEncString(String strMing) {
byte[] byteMi = null; 
byte[] byteMing = null;
byte[] encode = null;
String strMi = ""; 
// BASE64Encoder base64en = new BASE64Encoder(); 
try { 
byteMing = strMing.getBytes("UTF8"); 
byteMi = getEncCode(byteMing); 
// strMi = base64en.encode(byteMi); 
encode = Base64.encode(byteMi, Base64.DEFAULT);

catch(Exception e) { 
e.printStackTrace(); 

finally { 
// base64en = null; 
byteMing = null; 
byteMi = null; 

// return strMi; 
    return new String(encode);
} /** 
* 解密 :  String密文输入,String明文输出 
* @param strMi 
* @return 
*/ 
// public static String getDesString(String strMi) { 
//
//// BASE64Decoder base64De = new BASE64Decoder(); 
// byte[] byteMing = null; 
// byte[] byteMi = null;
// byte[] decode = null;
// String strMing = ""; 
// try { 
//// byteMi = base64De.decodeBuffer(strMi); 
//     decode = Base64.decode(encode, Base64.DEFAULT);
// byteMing = getDesCode(byteMi); 
// strMing = new String(byteMing, "UTF8"); 
// } 
// catch(Exception e) { 
// e.printStackTrace(); 
// } 
// finally { 
// base64De = null; 
// byteMing = null; 
// byteMi = null; 
// } 
// return strMing; 
// } 
/** 
* DES加密:以byte[]明文输入,byte[]密文输出 
* @param byteS 
* @return 
*/ 
private static byte[] getEncCode(byte[] byteS) { 

byte[] byteFina = null; 
Cipher cipher; 

try { 
cipher = Cipher.getInstance("DES"); 
cipher.init(Cipher.ENCRYPT_MODE, key); 
byteFina = cipher.doFinal(byteS); 

catch(Exception e) { 
e.printStackTrace(); 

finally { 
cipher = null; 

return byteFina; 

/** 
* 解密以byte[]密文输入,以byte[]明文输出 
* @param byteD 
* @return 
*/ 
private static byte[] getDesCode(byte[] byteD) { 
Cipher cipher; 
byte[] byteFina=null; 

try{ 
cipher = Cipher.getInstance("DES"); 
cipher.init(Cipher.DECRYPT_MODE, key); 
byteFina = cipher.doFinal(byteD); 
}catch(Exception e){ 
e.printStackTrace(); 
}finally{ 
cipher = null; 

return byteFina; 

解决方案 »

  1.   

    j2se平台上的代码如下:
    package com.qq.des;J2SE平台上的代码如下:
    import java.security.Key; 
    import java.security.SecureRandom; 
    import javax.crypto.Cipher; 
    import javax.crypto.KeyGenerator; import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    /**
     * all methods are static 
     * @author randyjia
     *
     */
    public class DES 

    private static Key key; 
    /** 
    * 根据参数生成KEY 
    * @param strKey 
    */ 
    public static void getKey(String strKey) { 
    try{ 
    KeyGenerator generator = KeyGenerator.getInstance("DES"); 
    generator.init(new SecureRandom(strKey.getBytes())); 
    key = generator.generateKey(); 
    // System.out.println("key is " + new String(key.getEncoded(),"UTF-8"));

    byte[] keyResult = key.getEncoded();
    System.out.println("key is ");
    for (int i = 0, n = keyResult.length;i < n; i ++){
    System.out.print(keyResult[i] + "  ");
    }
    System.out.println();

    generator = null; 
    }catch(Exception e){ 
    e.printStackTrace(); 


    /** 
    * 加密:  String明文输入,String密文输出 
    * @param strMing 
    * @return 
    */ 
    public static String getEncString(String strMing) {
    byte[] byteMi = null; 
    byte[] byteMing = null; 
    String strMi = ""; 
    BASE64Encoder base64en = new BASE64Encoder(); 
    try { 
    byteMing = strMing.getBytes("UTF8"); 
    byteMi = getEncCode(byteMing); 
    strMi = base64en.encode(byteMi); 

    catch(Exception e) { 
    e.printStackTrace(); 

    finally { 
    base64en = null; 
    byteMing = null; 
    byteMi = null; 

    return strMi; 
    }
    /**
     * 加密:不借助sun.misc.BASE64Decoder包,自定义实现的Base64编码
     * @param strMing
     * @return
     */
    public static String myGetEncString(String strMing){
    byte[] byteMi = null; 
    byte[] byteMing = null; 
    String strMi = "";  try { 
    byteMing = strMing.getBytes("UTF8"); 
    byteMi = getEncCode(byteMing); 
    strMi = Base64.encode(byteMi); 

    catch(Exception e) { 
    e.printStackTrace(); 

    finally { 
    byteMing = null; 
    byteMi = null; 

    return strMi; 
    }
    /** 
    * 解密 :  String密文输入,String明文输出 
    * @param strMi 
    * @return 
    */ 
    public static String getDesString(String strMi) { 

    BASE64Decoder base64De = new BASE64Decoder(); 
    byte[] byteMing = null; 
    byte[] byteMi = null; 
    String strMing = ""; 
    try { 
    byteMi = base64De.decodeBuffer(strMi); 
    byteMing = getDesCode(byteMi); 
    strMing = new String(byteMing, "UTF8"); 

    catch(Exception e) { 
    e.printStackTrace(); 

    finally { 
    base64De = null; 
    byteMing = null; 
    byteMi = null; 

    return strMing; 

    /**
     * 解密::不借助sun.misc.BASE64Decoder包,自定义实现的Base64编码
     * @param strMi
     * @return
     */
    public static String myGetDesString(String strMi){

    byte[] byteMing = null; 
    byte[] byteMi = null; 
    String strMing = ""; 
    try { 
    byteMi = Base64.decode(strMi); 
    byteMing = getDesCode(byteMi); 
    strMing = new String(byteMing, "UTF8"); 

    catch(Exception e) { 
    e.printStackTrace(); 

    finally { 
    byteMing = null; 
    byteMi = null; 

    return strMing; 
    }
    /** 
    * DES加密:以byte[]明文输入,byte[]密文输出 
    * @param byteS 
    * @return 
    */ 
    private static byte[] getEncCode(byte[] byteS) { 

    byte[] byteFina = null; 
    Cipher cipher; 

    try { 
    cipher = Cipher.getInstance("DES"); 
    cipher.init(Cipher.ENCRYPT_MODE, key); 
    byteFina = cipher.doFinal(byteS); 
    // System.out.println("DES加密结果:" + new String(byteFina,"UTF8").toString());
    System.out.println("encode result is");
    for (int i = 0, len = byteFina.length; i < len; i ++){
    System.out.print(byteFina[i] + " ");
    }
    System.out.println();

    catch(Exception e) { 
    e.printStackTrace(); 

    finally { 
    cipher = null; 

    return byteFina; 

    /** 
    * 解密以byte[]密文输入,以byte[]明文输出 
    * @param byteD 
    * @return 
    */ 
    private static byte[] getDesCode(byte[] byteD) { 
    Cipher cipher; 
    byte[] byteFina=null; 

    try{ 
    cipher = Cipher.getInstance("DES"); 
    cipher.init(Cipher.DECRYPT_MODE, key); 
    byteFina = cipher.doFinal(byteD); 
    }catch(Exception e){ 
    e.printStackTrace(); 
    }finally{ 
    cipher = null; 

    return byteFina; 
    } public static void main(String[] args){  String text = "CHINA";

    getKey("12345678");//生成密匙  String strEnc1 = getEncString(text); 
    System.out.println("encode = " + strEnc1); 

    String strEnc2 = myGetEncString(text);
    System.out.println("myencode = " + strEnc1); 

    String strDes1 = getDesString(strEnc1);
    String strDes2 = myGetDesString(strEnc2);

    System.out.println("decode = " + strDes1);
    System.out.println("my decode = " + strDes2);

    } 用到的Base64类如下:
    package com.qq.des;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;public class Base64 {
    private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    /**
     * data[]进行编码
     * @param data
     * @return
     */
        public static String encode(byte[] data) {
            int start = 0;
            int len = data.length;
            StringBuffer buf = new StringBuffer(data.length * 3 / 2);         int end = len - 3;
            int i = start;
            int n = 0;         while (i <= end) {
                int d = ((((int) data[i]) & 0x0ff) << 16)
                        | ((((int) data[i + 1]) & 0x0ff) << 8)
                        | (((int) data[i + 2]) & 0x0ff);             buf.append(legalChars[(d >> 18) & 63]);
                buf.append(legalChars[(d >> 12) & 63]);
                buf.append(legalChars[(d >> 6) & 63]);
                buf.append(legalChars[d & 63]);             i += 3;             if (n++ >= 14) {
                    n = 0;
                    buf.append(" ");
                }
            }         if (i == start + len - 2) {
                int d = ((((int) data[i]) & 0x0ff) << 16)
                        | ((((int) data[i + 1]) & 255) << 8);             buf.append(legalChars[(d >> 18) & 63]);
                buf.append(legalChars[(d >> 12) & 63]);
                buf.append(legalChars[(d >> 6) & 63]);
                buf.append("=");
            } else if (i == start + len - 1) {
                int d = (((int) data[i]) & 0x0ff) << 16;             buf.append(legalChars[(d >> 18) & 63]);
                buf.append(legalChars[(d >> 12) & 63]);
                buf.append("==");
            }         return buf.toString();
        }     private static int decode(char c) {
            if (c >= 'A' && c <= 'Z')
                return ((int) c) - 65;
            else if (c >= 'a' && c <= 'z')
                return ((int) c) - 97 + 26;
            else if (c >= '0' && c <= '9')
                return ((int) c) - 48 + 26 + 26;
            else
                switch (c) {
                case '+':
                    return 62;
                case '/':
                    return 63;
                case '=':
                    return 0;
                default:
                    throw new RuntimeException("unexpected code: " + c);
                }
        }     /**
         * Decodes the given Base64 encoded String to a new byte array. The byte
         * array holding the decoded data is returned.
         */     public static byte[] decode(String s) {         ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                decode(s, bos);
            } catch (IOException e) {
                throw new RuntimeException();
            }
            byte[] decodedBytes = bos.toByteArray();
            try {
                bos.close();
                bos = null;
            } catch (IOException ex) {
                System.err.println("Error while decoding BASE64: " + ex.toString());
            }
            return decodedBytes;
        }     private static void decode(String s, OutputStream os) throws IOException {
            int i = 0;         int len = s.length();         while (true) {
                while (i < len && s.charAt(i) <= ' ')
                    i++;             if (i == len)
                    break;             int tri = (decode(s.charAt(i)) << 18)
                        + (decode(s.charAt(i + 1)) << 12)
                        + (decode(s.charAt(i + 2)) << 6)
                        + (decode(s.charAt(i + 3)));             os.write((tri >> 16) & 255);
                if (s.charAt(i + 2) == '=')
                    break;
                os.write((tri >> 8) & 255);
                if (s.charAt(i + 3) == '=')
                    break;
                os.write(tri & 255);             i += 4;
            }
        }
        
        public static void main(String args[]){
         String text = "CHINA";
         String result = encode(text.getBytes());
         byte[] result1 = decode(result);
        
         System.out.println(result);
         System.out.println(new String(result1));
        
         BASE64Encoder base64En = new BASE64Encoder();
         System.out.println(base64En.encode(text.getBytes()));
         BASE64Decoder base64De = new BASE64Decoder(); 
         try {
    System.out.println(new String(base64De.decodeBuffer(base64En.encode(text.getBytes()))));
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
        }
    }
      

  2.   


    我用的都是包,其实关键就是下面:   KeyGenerator generator = KeyGenerator.getInstance("DES"); 
       generator.init(new SecureRandom(strKey.getBytes())); 
       key = generator.generateKey();
       Cipher cipher = Cipher.getInstance("DES"); 
       cipher.init(Cipher.ENCRYPT_MODE, key); 
       byteFina = cipher.doFinal(byteS);就只有输出,怎么一步步看?
    我打印过key,key生成都不一样。
      

  3.   


    我运行java版本,只要key不变,结果都是一样的(当然,加密的文本是一样的。),不会变化;
    android版本也是这样的,不会变化;
    郁闷的是,这两个不变的结果始终不一样。
      

  4.   

    同一平台多次生成key,结果是一样的?
    那key自己指定,不要程序生成了,可以吗?
      

  5.   

    是的,只要输入的key一样,结果就一样。
    但是两个平台的结果始终不一样
      

  6.   

    刚才,google"DES加密结果不一致",出来了一大把结果,结果不止android平台,C#、C++、PHP都有这种情况,肯定跟实现有关填充的模式有关
    下面是java和C#不能互通的例子
    http://topic.csdn.net/u/20091103/16/f04ae181-12aa-46a7-8d90-25976d820c6b.html
      

  7.   

    如果lz确定数据和密钥肯定一样的话,试着把数据大小端倒置一下lz可以尝试下,我不是很清楚这个问题是与操作系统有关还是与具体语言(或加密库)的代码实现有关
      

  8.   

    怎么个数据统一大小啊?
    我把key设为了8的倍数,应该不存在补齐的问题了。还望指教。或者给我一个测试用列。我网上找的测试用例都不行。
      

  9.   

    问题解决了。在我的博客有相应的解答
    http://blog.csdn.net/randyjiawenjie/article/details/6617225