经过一年的黑莓开发,总结一些东西,记录遇到过的一些问题。
这里主要记录跟AES128有关的问题: 黑莓端与java服务器端的相互加密与解密,两端用的都是AES/ECB/NoPadding
黑莓端:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import net.rim.device.api.crypto.AESDecryptorEngine;
import net.rim.device.api.crypto.AESEncryptorEngine;
import net.rim.device.api.crypto.AESKey;
import net.rim.device.api.crypto.BlockDecryptor;
import net.rim.device.api.crypto.BlockEncryptor;
import net.rim.device.api.crypto.CryptoTokenException;
import net.rim.device.api.crypto.CryptoUnsupportedOperationException;
import net.rim.device.api.io.NoCopyByteArrayOutputStream;
import net.rim.device.api.util.DataBuffer;
/*
* encryption and decryption with AES/ECB/NoPadding
*
* */
public class CryptoUtil {
public static byte[] encrypt(String content) throws CryptoTokenException,
CryptoUnsupportedOperationException, IOException{
//获取密码.
String keyStr=getKeyStr();
int len=content.length();
int cha=0;
//如果不是16的倍数就加上qwertyuiopasdfgh@字符串
if((cha=len%16)!=0){
for(int i=0;i<16-cha;i++){
content+="qwertyuiopasdfgh@";
}
}
byte[] data=content.getBytes("UTF-8");
byte[] keyData=keyStr.getBytes();
AESKey key=new AESKey(keyData);
NoCopyByteArrayOutputStream out=new NoCopyByteArrayOutputStream();
AESEncryptorEngine engine=new AESEncryptorEngine(key);//创建加密引擎
BlockEncryptor encryptor=new BlockEncryptor(engine, out);//创建BlockEncryptor隐藏引擎的细节
encryptor.write(data, 0, data.length);
int finalLength=out.size();
byte[] cbytes = new byte[finalLength];
System.arraycopy(out.getByteArray(), 0, cbytes, 0, finalLength);
return cbytes;
}
public static String decrypt(byte[] content) throws CryptoTokenException,
CryptoUnsupportedOperationException, IOException{
//获取密码.
String keyStr=getKeyStr();
byte[] keyData=keyStr.getBytes();
// 首先,创建AESKey。
AESKey key=new AESKey(keyData);
// 创建解密引擎。
AESDecryptorEngine engin=new AESDecryptorEngine(key);
// 创建BlockDecryptor隐藏解密细节。
ByteArrayInputStream input = new ByteArrayInputStream(content);
BlockDecryptor decryptor=new BlockDecryptor(engin, input);
// 读取数据
byte[] temp = new byte[100];
DataBuffer buffer = new DataBuffer();
int pos=0;
while((pos=decryptor.read(temp))>0){
buffer.write(temp,0, pos);
}
byte[] plaintextAndHash = buffer.getArray();
String str=new String(plaintextAndHash,0,plaintextAndHash.length,"UTF-8");
// 如果position>0说明填充过字符串qwertyuiopasdfgh@
int position=str.indexOf("qwertyuiopasdfgh@");
if(position>0){
str=str.substring(0, position);
}
str=str.trim();
int pos1=str.lastIndexOf('>');
if(pos1<str.length()&&pos1>=0){
str=str.substring(0, pos1+1);
}
return str.trim();
}
//获取秘钥
private static String getKeyStr(){
return "1234567890123456";
}
}
java端:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
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.SecretKeySpec;
public class CryptoUtil {
public static byte[] encrypt(String content) throws NoSuchAlgorithmException,
NoSuchPaddingException,InvalidKeyException,UnsupportedEncodingException{
String keyStr=getKeyStr();
int len=content.length();
int cha=0;
//如果不是16的倍数就加上qwertyuiopasdfgh@字符串
if((cha=len%16)!=0){
for(int i=0;i<16-cha;i++){
content+="qwertyuiopasdfgh@";
}
}
byte[] data=content.getBytes("UTF-8");
byte[] keyData=keyStr.getBytes();
//使用AES/ECB/NoPadding
Cipher aes=Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec key=new SecretKeySpec(keyData, "AES");
aes.init(Cipher.ENCRYPT_MODE, key);
byte[] cleartext = aes.update(data, 0, data.length);
return cleartext;
}
public static String decrypt(byte[] content) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, UnsupportedEncodingException{
String keyStr=getKeyStr();
byte[] keyData=keyStr.getBytes();
//使用AES/ECB/NoPadding
Cipher aes=Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec key=new SecretKeySpec(keyData, "AES");
aes.init(Cipher.DECRYPT_MODE, key);
byte[] cleartext = aes.update(content, 0, content.length);
String str=new String(cleartext,0,cleartext.length,"UTF-8");
int position=str.indexOf("qwertyuiopasdfgh@");
if(position>0){
str=str.substring(0, position);
}
return str.trim();
}
//获取秘钥
private static String getKeyStr(){
return "1234567890123456";
}
/**将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
byte[] result=new byte[hexStr.length()/2];
for(int i=0;i<hexStr.length()/2;i++){
int high=Integer.parseInt(hexStr.substring(i*2, i*2+1),16);
int low=Integer.parseInt(hexStr.substring(i*2+1, i*2+2),16);
result[i]=(byte)(high*16+low);
}
return result;
}
/**将二进制转换成16进制
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb=new StringBuffer();
for(int i=0;i<buf.length;i++){
String hex=Integer.toHexString(buf[i]&0xFF);
if(hex.length()==1){
hex='0'+hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}