前段时间负责开发了javaweb后台与android端的通信接口,其中传递了一些重要信息需要加密处理,我们使用了最常见的DES,加解密的核心代码如下:
/**
* 加密方法
*/
private byte [] encryptByte(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) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
cipher = null ;
}
return byteFina;
}
public String encryptStr(String strMing) {
byte [] byteMi = null ;
byte [] byteMing = null ;
String strMi = "" ;
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes( "UTF8" );
byteMi = this .encryptByte(byteMing);
strMi = base64en.encode(byteMi);
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
base64en = null ;
byteMing = null ;
byteMi = null ;
}
return strMi;
}
/**
* 解密方法
*
* @param strMi
* @return
*/
private byte [] decryptByte( 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) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
cipher = null ;
}
return byteFina;
}
public String decryptStr(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
byte [] byteMing = null ;
byte [] byteMi = null ;
String strMing = "" ;
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = this .decryptByte(byteMi);
strMing = new String(byteMing, "UTF8" );
} catch (Exception e) {
throw new RuntimeException(
"Error initializing SqlMap class. Cause: " + e);
} finally {
base64De = null ;
byteMing = null ;
byteMi = null ;
}
return strMing;
}
/**
* 使用方式
*/
public static void main(String[] args) throws Exception {
DesTester des = new DesTester( "key" );
String str1 = "这是用来加密的文字" ;
String str2 = des.encryptStr(str1);
String deStr = des.decryptStr(str2);
System. out .println( " 加密前: " + str1);
System. out .println( " 加密后: " + str2);
System. out .println( " 解密后: " + deStr);
}
令人始料未及的是,对于同一串加密信息(一般是字符串),jdk与android sdk加密出来的东西完全不一样,以至于无法对交互中接收到的数据进行解密。
百度了一些资料,了解了一下大概原因,原文解释如下(参考出处:http://www.docin.com/p-438365141.html):
调用DES加密算法最精要的就是下面两句话:
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
CBC是工作模式,DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB),
PKCS5Padding是填充模式,还有其他的填充模式:
然后,cipher.init()一共有三个参数:Cipher.ENCRYPT_MODE、key、zeroIv,zeroIv就是初始化向量,一个8位字符数组。
工作模式、填充模式、初始化向量这三种因素一个都不能少。否则,如果你不制定的话,那么程序就要调用默认实现。问题就来了,这就与平台有关了。
这两段话把原理解释的非常清楚,不过有一些细节还可以深挖一下。
1、工作模式的机制,度娘到一个可参考文章:http://wenku.baidu.com/view/8e329bc50c22590102029d3d.html
2、初始化向量的作用;
找到这样一个解释:初始化向量那是PBE密钥加密,没有向量的那是普通的加密,对安全方面来说PBE更安全些。
根据以上的分析,把加解密方法再重新修改一下:
/**
* DES加密
*/
public static String encryptDES(String encryptString){
IvParameterSpec zeroIv = new IvParameterSpec(iv);
SecretKeySpec key = new SecretKeySpec(keyStr.getBytes(), "DES");
Cipher cipher;
try {
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(encryptString.getBytes("utf-8"));
return Base64.encode(encryptedData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* DeS解密
*/
public static String decryptDES(String decryptString){
byte[] byteMi = Base64.decode(decryptString);
IvParameterSpec zeroIv = new IvParameterSpec(iv);
SecretKeySpec key = new SecretKeySpec(keyStr.getBytes(), "DES");
Cipher cipher;
try {
cipher = Cipher.getInstance("DES/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 (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 使用方式
*/
public static void main(String[] args) {
String str = "这是一个待加密的信息";
String jiamiStr = DESUtil.encryptDES(str);
String jiemiStr = DESUtil.decryptDES(jiamiStr);
System.out.println("未加密:"+str);
System.out.println("加密:"+jiamiStr);
System.out.println("解密:"+jiemiStr);
}
开发的环境是eclipse+jetty,以上代码在与android端联调时可正常通信。但打成war包部署到win2003+tomcat上之后,解密的信息却出现了乱码,可笑的是部分乱码而另一部分正常。又折腾了好一阵子,把编码从"utf-8"修改为"gb2312",这才能正常加解密。
一直到现在也没有完全搞清楚,为什么能win2003服务器在"utf-8"的编码设置下,能正常显示web页面,却不能支持加解密通信。
分享到:
相关推荐
本项目在Android系统上实现了DES加密通话功能,使用TCP传送数据。由于是为了学习DES加密,所以做的比较简单,语音通话的降噪和回音消除都没有实现。项目中的两个文件夹分别是服务器项目和Android应用项目。两者都是...
4. **OpenPGP支持**:除了标准的加密和签名,Bouncy Castle还实现了OpenPGP标准,支持加密邮件和数据交换。 5. **SSL/TLS协议实现**:Bouncy Castle可以作为SSL/TLS客户端或服务器端的实现,增加了对一些非标准协议...
本项目在Android系统上实现了DES加密通话功能,使用TCP传送数据。由于是为了学习DES加密,所以做的比较简单,语音通话的降噪和回音消除都没有实现。项目中的两个文件夹分别是服务器项目和Android应用项目。两者都是...
2. **对称加密**:使用同一密钥进行加密和解密,如AES、DES。 3. **非对称加密**:使用一对公钥和私钥,公钥用于加密,私钥用于解密,如RSA、ECC。 4. **哈希函数**:将任意长度的输入转换为固定长度的输出,如MD5、...
BCryptProv-jdk15on-1.68.jar 是一个关键的Java库,主要用于加密和安全相关的操作。这个库是Bouncy Castle提供的,Bouncy Castle是一个著名的开源密码学软件项目,提供了大量的加密算法、协议实现以及相关的工具。...
- **原理**: DES是一种对称加密算法,使用56位密钥对数据进行加密和解密。 - **过程**: 包括初始置换、循环函数、中间置换等步骤。 - **优缺点**: 加密速度快,但安全性相对较低。 #### 3 系统分析与设计 - **...
1. **生成密钥对**:使用Bouncy Castle,开发者可以生成RSA、DSA、EC等不同类型的密钥对,这些密钥对可以用于加密和解密数据,以及进行数字签名和验证。 2. **创建KeyStore**:Bouncy Castle提供了创建和管理BKS ...
bcprov-jdk15on-151.jar是基础版本,包含了标准的加密算法和功能,如RSA、AES、DES等,满足日常的加密需求。而bcprov-ext-jdk15on-151.jar则包含了一些扩展功能,比如非标准的密码算法、更全面的证书处理能力等,...
例如,bcprov-jdk16-1.46.jar和bcmail-jdk16-1.46.jar对于需要进行高级加密和邮件安全的Java应用程序来说非常关键;lcrypto-j2me-138.jar则为Java ME环境提供了必要的加密功能,适用于移动设备或嵌入式系统;而...
- **数据加密和解密**:应用内的敏感数据存储,例如用户密码,可以使用BouncyCastle提供的加密算法进行保护,增加数据的安全性。 - **数字签名和验签**:在Android应用中,BouncyCastle可用于创建和验证文件或数据...
应用程式Android 适用于Android的MOPCON App由react-native 0.59.8构建 安装命令和开发工具 这个项目是使用react-native开发的,因此在开始之前,我们应该安装以下命令和工具。...安全文件已加密到secrets.t
在java中有一个框架叫commons-codec框架,它是由apache出品的开源项目之一,其中集成了大量的解密加密工具类,是一个强大的解密加密工具包,其中包括常用的md5,des,base64,url,sha1,sha128,sha256等各种加密...