AndroidとjavaプラットフォームDES暗号解読相互接続プログラムとその相互接続できない原因

6845 ワード

ネット上のdemoはたくさん検索されていますが、基本的には一知半解です(私も含めて).なぜでしょうか.2つのプラットフォームで暗号化しようとしたところ、Android DES暗号化とjava DES暗号化のプログラムが互いに通じないことに気づきました.暗号化の結果が違うのです.ましてやAndroidプラットフォームの暗号化入力はjava DESの復号として出力されています.そうするとクライアントとサーバ側は通信できなくなります.私もネット上では以前から投稿して多くの人に聞いたが、答えは満足しなかった.今日、会社の部門のもう一人の同僚が私に言って、やっとこの通じない問題を解決しました.DES暗号化アルゴリズムパッケージを呼び出すには、次の2つの言葉が必要です.
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

CBCは動作モードであり、DESには電子暗号本モード(ECB)、暗号化パケットリンクモード(CBC)、暗号化フィードバックモード(CFB)、出力フィードバックモード(OFB)の4つのモードがあり、PKCS 5 Paddingは充填モードであり、その他の充填モードもある:そしてcipher.init()には3つのパラメータがある:Cipher.ENCRYPT_MODE,key,zeroIv,zeroIvは初期化ベクトルであり,8は文字配列である.動作モード、充填モード、初期化ベクトルの3つの要因はいずれも少なくない.そうでなければ、指定しない場合は、プログラムがデフォルトのインプリメンテーションを呼び出す必要があります.問題が来ました.これはプラットフォームと関係があります.道理でネット上で「DES暗号化結果が一致しない」と検索すると、nページ以上の結果が出てくる.(以前はIVを指定していなかったが、2週間苦しめられた)ソースプログラムは以下の通りである(javaプラットフォームからandroidプラットフォームまで、私はコードを変更していない):また、一般的には暗号化後の結果はbase 64符号化で伝送される.javaプラットフォーム:メインプログラム
public class testDES {

/**

* @param args

* @throws Exception 

*/

public static void main(String[] args) throws Exception {

// TODO Auto-generated method stub

String key = "12345678";

String text = "12345678";

String result1 = DES.encryptDES(text,key);

String result2 = DES.decryptDES(result1, key);

System.out.println(result1);

System.out.println(result2);

}

}

使用するDES暗号化クラス
import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

public class DES {

private static byte[] iv = {1,2,3,4,5,6,7,8};

public static String encryptDES(String encryptString, String encryptKey) throws Exception {

//		IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);

IvParameterSpec zeroIv = new IvParameterSpec(iv);

SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

byte[] encryptedData = cipher.doFinal(encryptString.getBytes());

return Base64.encode(encryptedData);

}

public static String decryptDES(String decryptString, String decryptKey) throws Exception {

byte[] byteMi = new Base64().decode(decryptString);

IvParameterSpec zeroIv = new IvParameterSpec(iv);

//		IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);

SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);

byte decryptedData[] = cipher.doFinal(byteMi);

return new String(decryptedData);

}

}

使用するBASE 64ツールクラス:
import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.OutputStream;

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;

}

}

}

adnroidプラットフォームのメイン関数:
public class main extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

String key = "12345678";

String text = "12345678";

try {

String result1 = DES.encryptDES(text,key);

String result2 = DES.decryptDES(result1, key);

Log.i("DES encode text is ", result1);

Log.i("DES encode text is ", result2);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}    

}

}

ログログを表示すると結果が表示されます.両プラットフォームの結果は同じで、暗号化結果:X 2 p 9 Uo 45 Tzk 6 Ntu 6 W 7 Ev+Q==
復号結果:12345678
本文は“清源教育”のブログから出て、転載してここhttp://blog.csdn.net/tsingyuan2012/article/details/11473597を明記してください、ありがとうございます!