当前位置: 代码迷 >> Android >> android客户端和java服务端用aes加密结果不一样的解决办法
  详细解决方案

android客户端和java服务端用aes加密结果不一样的解决办法

热度:62   发布时间:2016-04-27 23:25:45.0
android客户端和java服务端用aes加密结果不一样的解决方法。

转载请注明出处,谢谢http://blog.csdn.net/harryweasley/article/details/47746521


最近在公司做一个项目,老大让我们实现加解密的方法,我把工作直接推给了java服务端,他们也是直接在网上copy的代码,说我直接放到我的android代码中就可以了,不需要太多的更改。我就照做了,但是在真正的测试的时候,发现两边输入的密码一致,但是加密结果不一致。这可折磨我们了好久,最终解决了这个问题,加以记录。


android和java加密结果不一样的原因,是因为他们的默认随机数序列不一致,所以解决他的办法是,不要使用默认的创建方法。


以下是正确的代码。android和java端的代码是一致的。


先看MainActivity中的代码。注意,这里的密码个数是16个数字。


package com.example.aesdemo;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		String content="thisistest";		String password="1259632153695615";		String jiamiresult=AesUtil.aesEncrypt(content, password);		Log.i("tag", "加密结果"+jiamiresult);		String jiemi=AesUtil.aesDecrypt(jiamiresult, password);				Log.i("tag", "解密结果"+jiemi);	}}


logcat中打印的结果是:


再看AesUtil中的代码。


package com.example.aesdemo;import java.io.UnsupportedEncodingException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AesUtil {	public static final String VIPARA = "1269571569321021";	public static final String bm = "GBK";	/**	 * 字节数组转化为大写16进制字符串	 * 	 * @param b	 * @return	 */	private static String byte2HexStr(byte[] b) {		StringBuilder sb = new StringBuilder();		for (int i = 0; i < b.length; i++) {			String s = Integer.toHexString(b[i] & 0xFF);			if (s.length() == 1) {				sb.append("0");			}			sb.append(s.toUpperCase());		}		return sb.toString();	}	/**	 * 16进制字符串转字节数组	 * 	 * @param s	 * @return	 */	private static byte[] str2ByteArray(String s) {		int byteArrayLength = s.length() / 2;		byte[] b = new byte[byteArrayLength];		for (int i = 0; i < byteArrayLength; i++) {			byte b0 = (byte) Integer.valueOf(s.substring(i * 2, i * 2 + 2), 16)					.intValue();			b[i] = b0;		}		return b;	}	/**	 * AES 加密	 * 	 * @param content	 *            明文	 * @param password	 *            生成秘钥的关键字	 * @return	 */	public static String aesEncrypt(String content, String password) {		try {			IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());			SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");			cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);			byte[] encryptedData = cipher.doFinal(content.getBytes(bm));						return Base64.encode(encryptedData);//			return byte2HexStr(encryptedData);		} catch (NoSuchAlgorithmException e) {			e.printStackTrace();		} catch (NoSuchPaddingException e) {			e.printStackTrace();		} catch (UnsupportedEncodingException e) {			e.printStackTrace();		} catch (InvalidKeyException e) {			e.printStackTrace();		} catch (IllegalBlockSizeException e) {			e.printStackTrace();		} catch (BadPaddingException e) {			e.printStackTrace();		} catch (InvalidAlgorithmParameterException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * AES 解密	 * 	 * @param content	 *            密文	 * @param password	 *            生成秘钥的关键字	 * @return	 */	public static String aesDecrypt(String content, String password) {		try {			byte[] byteMi = Base64.decode(content);//			byte[] byteMi=	str2ByteArray(content);			IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());			SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");			cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);			byte[] decryptedData = cipher.doFinal(byteMi);			return new String(decryptedData, "utf-8");		} catch (NoSuchAlgorithmException e) {			e.printStackTrace();		} catch (NoSuchPaddingException e) {			e.printStackTrace();		} catch (InvalidKeyException e) {			e.printStackTrace();		} catch (IllegalBlockSizeException e) {			e.printStackTrace();		} catch (BadPaddingException e) {			e.printStackTrace();		} catch (UnsupportedEncodingException e) {			e.printStackTrace();		} catch (InvalidAlgorithmParameterException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}}

你们可以看到,我有两行是注释掉的,其实,也可以分别注释上面的base64的,把之前注释的释放,也是可以的。


这里没有注释的,是base64的方式。

不要用android自带的Base64类,用以下的这个。

package com.example.aesdemo;import java.io.ByteArrayOutputStream;  import java.io.IOException;  import java.io.OutputStream; public class Base64 {	private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"			.toCharArray();	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;		}	}}


关于什么是Base64编码,你可以查看http://blog.csdn.net/harryweasley/article/details/47746533


版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案