- 浏览: 236160 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
ly8666:
十分感谢。。谢谢
一个完整的混合加密方式在Socket客户机服务器通信应用中的例子 -
blaiu:
打个包传上来?
用CSS实现下拉菜单的多种方法 -
kk_luan:
至支持IE,但不能支持IE9
JavaScript关闭当前网页,不用提示 -
lishaorui:
刚好需要,试了下,很好。
android技巧:apk文件反编译以及签名打包(dex2jar&jd,apktool,apk-sign) -
shaopengxiang:
有没有源码哈? 能共享吗?
DroidInfo v0.2.1 手机信息查询应用
按:下面的文字涉及早已在工程中广泛采用的混合加密方式,对此熟知者就不用往下看了,以免浪费时间。
我们知道,现代加密方式有两大类:一类是对称加密方式,其优点是加密速度快,缺点是密钥不便于传递,其中典型例子是AES;一类是非对称加密方式,优点是交换钥匙方便,缺点是加密时间长。在实际应用,我们可以取其所长,弃其所短,这就是混合加密方式,有的场合也成为Hybrid方式。
具体来说混合加密方式的工作过程大体是这样:首先,客户端将明文用本地的AES钥匙加密,然后从服务器端得到服务器端的RSA公钥,用它来对本地的AES钥匙加密,然后把两端密文拼合在一起送给服务器端;服务器端得到密文后,将其拆分成密钥文和密文两段,然后,用本地的RSA私钥对密钥文进行解密,得到加密密文的AES钥匙,然后用AES钥匙对密文解密,得到明文。在此过程中,对明文加密和对密文解密都采用了对称加密解密方式,速度快,且都在服务器客户机的一侧进行,没有通过网络传输,安全性高;而网络传输的是服务器的RSA公钥和经其加密的AES钥匙,即使被截获也没有什么好担心的。如果要双向传递则把这个过程反过来就可以了。
以上过程的示意UML SEQUENCE图如下:
下面用代码来辅助说明一下。
客户端进行加密并传输密文到服务器端的代码,其中,服务器端的RSA公钥已经用别的方法得到了,下面serverPublicKey变量就存储了它:
InputStream inStram=s.getInputStream();
OutputStream outStream=s.getOutputStream();
// 输出
PrintWriter out=new PrintWriter(outStream,true);
// 待加密的明文
StringBuilder sb1=new StringBuilder();
sb1.append("<request>");
sb1.append("<command>register</command>");
sb1.append("<username>何杨</username>");
sb1.append("<password>123456</password>");
sb1.append("</request>");
String plainText=sb1.toString();
// 对明文进行AES加密
byte[] aesArr=aesCoder.getEncryptByteArray(plainText); // 对明文进行AES加密
String cipherText=Base64.encodeBase64String(aesArr);// 得到AES加密后的密文
// 使用RSA对AES密钥进行加密
String key=aesCoder.getAesKey();// 取得AES的密钥
byte[] rsaArr=rsaCoder.getEncryptArray(key, serverPublicKey);
String encryptedKey=Base64.encodeBase64String(rsaArr);
// 在发出的密文前附带经服务器RSA公钥加密的AES密钥
String request="<key>"+encryptedKey+"</key>"+cipherText;
out.print(request);
out.flush();
s.shutdownOutput();// 输出结束
从上面这段代码可以看出,想发送到服务器端的明文是:
通过这段代码的处理后,最终发送到服务器端的密文是,
b6PMzQxKHzipSYw3ishH/3KxoYF8bkQGn2PkMNsn+xL1Gz6XgJcQ+B700hYvVT2FFPfelVz3VNlB
KhwVIE6h8LyD4w/SxhE=
</key>J4TsMoB3l8Cy91a9v6O0TADXZvKEkDPZ3E5noeu2dImfdsM55urhEY7lFAAsXm0AB4/jUL1h1lNP
cafz9srORh7h8NCb4760XnrBA5Q2JQrqwr1TGsB3oGq2Ha+FOLoFcI2Ab/wjEiAhe/kB6ZTgTA==
服务器端的处理代码:
String cipherText="";// 经客户端AES加密的密文
// 用正则表达式得到密钥文和密文
String regex="<key>(.+)</key>(.+)";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(request);
while(matcher.find()){
cipheredAesKey=matcher.group(1);
cipherText=matcher.group(2);
break;
}
// 得到经过服务器RSA私钥解密后的AES密钥
String plainAesKey="";
try {
byte[] cipheredAesKeyArr=Base64.decodeBase64(cipheredAesKey);
plainAesKey=model.getRsaCoder().getDecryptString(cipheredAesKeyArr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 使用AES密钥解密出明文
byte[] cipherTextArr=Base64.decodeBase64(cipherText);
String plainText=model.getAesCoder().getDecryptString(cipherTextArr, plainAesKey);
这段代码的输入是:
而经过拆分和解密后,AES密钥是:
用得到的AES密钥解密后,最终得到的明文部分是:
到这里,密文的还原工作就完成了。如果服务器端要向客户端发回处理后的结果,把上述过程再做一遍就可以了,注意一点,客户端要把自己的RSA公钥发过来,也就是说传递的文本中还要增加一个节点,这样服务器端就有了客户端的RSA公钥对服务器端的AES钥匙进行加密。
这种方式看似比纯RSA方式和AES方式都复杂了一点,但考虑到网络传输的安全性和速度,多写一些代码是完全值得的。
上文中用到的AESSecurityCoder类代码如下:
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* AES加密解密类
* 说明:
* 作者:何杨(heyang78@gmail.com)
* 创建时间:2010-12-25 下午12:19:12
* 修改时间:2010-12-25 下午12:19:12
*/
public class AESSecurityCoder{
// 加密方法
private static final String Algorithm="AES";
// 进行加密解密的密钥
private String aesKey="";
/**
* 构造函数
* @throws NoSuchAlgorithmException
*/
public AESSecurityCoder() throws NoSuchAlgorithmException{
KeyGenerator kg=KeyGenerator.getInstance(Algorithm);
kg.init(256);
SecretKey sk=kg.generateKey();
byte[] arr=sk.getEncoded();
aesKey=new String(Hex.encodeHex(arr));
}
/**
* 取得解密后的字符串
*
* 说明:
* @param encryptArr
* @return
* 创建时间:2010-12-1 下午03:33:31
*/
public String getDecryptString(byte[] encryptArr){
try{
Cipher cp=Cipher.getInstance(Algorithm);
cp.init(Cipher.DECRYPT_MODE, getKey());
byte[] arr=cp.doFinal(encryptArr);
return new String(arr);
}
catch(Exception ex){
System.out.println("无法进行解密,原因是"+ex.getMessage());
return null;
}
}
/**
* 传入密钥,得到解密后的字符串
*
* 说明:
* @param encryptArr
* @param aesKey
* @return
* 创建时间:2010-12-25 下午01:55:42
*/
public String getDecryptString(byte[] encryptArr,String aesKeyIn){
try{
Cipher cp=Cipher.getInstance(Algorithm);
byte[] arr1=Hex.decodeHex(aesKeyIn.toCharArray());
cp.init(Cipher.DECRYPT_MODE, new SecretKeySpec(arr1,Algorithm));
byte[] arr=cp.doFinal(encryptArr);
return new String(arr);
}
catch(Exception ex){
System.out.println("无法进行解密,原因是"+ex.getMessage());
return null;
}
}
/**
* 取得加密后的字节数组
*
* 说明:
* @param originalString
* @return
* 创建时间:2010-12-1 下午03:33:49
*/
public byte[] getEncryptByteArray(String originalString){
try{
Cipher cp=Cipher.getInstance(Algorithm);
cp.init(Cipher.ENCRYPT_MODE, getKey());
return cp.doFinal(originalString.getBytes());
}
catch(Exception ex){
System.out.println("无法进行加密,原因是"+ex.getMessage());
return null;
}
}
/**
* 取得密钥
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:33:17
*/
private Key getKey() throws Exception{
byte[] arr=Hex.decodeHex(aesKey.toCharArray());
return new SecretKeySpec(arr,Algorithm);
}
/**
* 取得AES加密钥匙
*
* 说明:
* @return
* 创建时间:2010-12-25 下午12:27:16
*/
public String getAesKey() {
return aesKey;
}
}
上文中用到的RSASecurityCoder类代码如下:
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* RSA加密解密类
* 说明:
* 作者:何杨(heyang78@gmail.com)
* 创建时间:2010-12-1 下午06:14:38
* 修改时间:2010-12-1 下午06:14:38
*/
public class RSASecurityCoder{
// 非对称加密密钥算法
private static final String Algorithm="RSA";
// 密钥长度,用来初始化
private static final int Key_Size=1024;
// 公钥
private byte[] publicKey;
// 私钥
private byte[] privateKey;
/**
* 构造函数,在其中生成公钥和私钥
* @throws Exception
*/
public RSASecurityCoder() throws Exception{
// 得到密钥对生成器
KeyPairGenerator kpg=KeyPairGenerator.getInstance(Algorithm);
kpg.initialize(Key_Size);
// 得到密钥对
KeyPair kp=kpg.generateKeyPair();
// 得到公钥
RSAPublicKey keyPublic=(RSAPublicKey)kp.getPublic();
publicKey=keyPublic.getEncoded();
// 得到私钥
RSAPrivateKey keyPrivate=(RSAPrivateKey)kp.getPrivate();
privateKey=keyPrivate.getEncoded();
}
/**
* 用公钥对字符串进行加密
*
* 说明:
* @param originalString
* @param publicKeyArray
* @return
* @throws Exception
* 创建时间:2010-12-1 下午06:29:51
*/
public byte[] getEncryptArray(String originalString,byte[] publicKeyArray) throws Exception{
// 得到公钥
X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyArray);
KeyFactory kf=KeyFactory.getInstance(Algorithm);
PublicKey keyPublic=kf.generatePublic(keySpec);
// 加密数据
Cipher cp=Cipher.getInstance(Algorithm);
cp.init(Cipher.ENCRYPT_MODE, keyPublic);
return cp.doFinal(originalString.getBytes());
}
/**
* 使用私钥进行解密
*
* 说明:
* @param encryptedDataArray
* @return
* @throws Exception
* 创建时间:2010-12-1 下午06:35:28
*/
public String getDecryptString(byte[] encryptedDataArray) throws Exception{
// 得到私钥
PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(privateKey);
KeyFactory kf=KeyFactory.getInstance(Algorithm);
PrivateKey keyPrivate=kf.generatePrivate(keySpec);
// 解密数据
Cipher cp=Cipher.getInstance(Algorithm);
cp.init(Cipher.DECRYPT_MODE, keyPrivate);
byte[] arr=cp.doFinal(encryptedDataArray);
// 得到解密后的字符串
return new String(arr);
}
/**
* 取得数组形式的公钥
*
* 说明:
* @return
* 创建时间:2010-12-25 上午07:50:04
*/
public byte[] getPublicKey() {
return publicKey;
}
/**
* 取得字符串形式的公钥
*
* 说明:
* @return
* 创建时间:2010-12-25 上午07:51:11
*/
public String getPublicKeyString() {
return Base64.encodeBase64String(getPublicKey());
}
public static void main(String[] arr) throws Exception{
String str="你好,世界! Hello,world!";
System.out.println("准备用公钥加密的字符串为:"+str);
// 用公钥加密
RSASecurityCoder rsaCoder=new RSASecurityCoder();
byte[] publicKey=rsaCoder.getPublicKey();
byte[] encryptArray=rsaCoder.getEncryptArray(str, publicKey);
System.out.print("用公钥加密后的结果为:");
for(byte b:encryptArray){
System.out.print(b);
}
System.out.println();
// 用私钥解密
String str1=rsaCoder.getDecryptString(encryptArray);
System.out.println("用私钥解密后的字符串为:"+str1);
}
}
好了,感谢您看到这里,希望它没有太多耽误您的宝贵时间。
发表评论
-
开源网络爬虫Snaker 15个漂亮的jQuery导航菜单
2012-01-15 14:23 1386开源网络爬虫Snaker http://www.blogja ... -
web文件下载,路径或文件名中文乱码
2011-07-08 18:14 2367/** * 附件下载 * @para ... -
用CSS实现下拉菜单的多种方法
2011-02-11 17:18 1904横向下拉菜单 <!DOCTYPE html PU ... -
javascript下拉菜单
2011-01-28 15:41 982<!DOCTYPE html PUBLIC &qu ... -
第三方WebServices调用网址(开放式基金数据、股票行情数据等)
2010-12-22 10:16 2028本文整理分享给大家常用第三方WebServices服务 ... -
调用Sina股票数据
2010-12-22 10:15 5844sina股票数据接口以大秦铁路(股票代码:601006)为例, ... -
分享文章到新浪微博(源码)
2010-07-02 07:28 3111<a title="新浪微博 ... -
关于文字与图片对齐问题
2010-06-13 17:28 1671通常图片与文字放在一起的时候图片往往会偏上,通过设置margi ...
相关推荐
#### 混合加密方案及其在即时通讯中的应用 随着互联网技术的飞速发展,即时通讯(Instant Messaging, IM)已成为人们日常沟通的重要手段之一。然而,即时通讯系统在便捷性的同时也面临着诸多安全挑战,如数据泄露、...
该系统可以广泛应用于计算机网络和计算机通讯技术中,提供安全的数据加密和解密服务。 本文提出了一个基于DES算法和RSA算法的混合密码系统,克服了两种算法的缺点,实现了优势互补。这项技术可以广泛应用于计算机...
此外,还可能存在混合加密方案,即结合对称和非对称加密的优点,使用非对称加密来安全地交换对称密钥,然后用对称密钥进行实际的语音数据加密。 语音通信加密系统还需要考虑到端到端的完整性,确保数据在传输过程中...
在IT行业中,P2P(Peer-to-Peer)技术是一种通信模式,它允许网络上的设备直接互相连接,而不需要通过中央服务器进行数据交换。QQ,作为中国最流行的即时通讯软件之一,其背后的通信机制虽然复杂,但我们可以用P2P...
在这个主题中,我们主要探讨实现混合放号的方法以及其在通信网络系统中的应用。 混合放号的核心是提供多样化的账号获取途径,包括但不限于手机号码、邮箱地址、社交账号绑定等。这样做的目的是为了提高用户体验,...
在信息安全日益重要的今天,Speak Fleely的源代码中应包含了安全机制,如使用SSL/TLS进行数据加密,保护用户的隐私和通话内容不被窃听。 八、平台兼容性与跨设备支持 考虑到用户可能在不同的设备上使用,Speak ...
3. **数据压缩与加密**:为减少网络延迟并保证信息安全,游戏数据在传输前通常会进行压缩和加密。压缩能减小数据量,提高传输效率;加密则保护玩家隐私和游戏数据安全。 4. **同步算法**:为了保持游戏状态的一致性...
1. **基金会现场总线(Foundation Fieldbus,简称FF)**:采用了OSI模型中的物理层、数据链路层和应用层为基础,并在其应用层上添加了用户层。 2. **LonWorks**:采用了OSI全部七层协议。 3. **Profibus**:同样采用...
中间人攻击是一种拦截、篡改或者伪装成通信双方进行通讯的攻击方式。这种攻击类型常见于不安全的Wi-Fi网络和未加密的通信协议中。 5. Web 在网络安全的背景下,Web可能指代针对网络应用的攻击和防护手段,例如SQL...
在热电改造项目中,根据现场环境和设备分布,可能需要采用混合型拓扑,以兼顾效率和可靠性。 此外,安全性和加密技术是通讯连接的重要组成部分。为防止未经授权的访问和数据篡改,需要使用如SSL/TLS协议进行数据...
综合来看,信息安全是保护信息在存储、处理、传输过程中不受到威胁和损害,确保信息的机密性、完整性和可用性。随着技术的发展和威胁的增多,信息安全的策略和防护措施也在不断演进,以适应新的挑战。对于信息安全的...
本系统采用混合式P2P网络结构,其中服务器仅作为注册和连接管理的角色,实际通讯在客户端之间直接进行。 - **网络编程**:系统使用Winsock库来进行网络编程。Winsock是Windows平台下的套接字编程接口,支持TCP/IP等...
1. 信息定义:信息是经过加工的特定形式的数据,它包含了关于客观事实可通讯的知识,且是有意义的。数据是信息的表现形式,但信息是数据的有意义的表示。 2. 信息系统组成:信息系统由软件和硬件、数据和网络、人员...
设计的过程中必须依据国家各种有关安全法规政策,对硬件支撑 平台的访问控制、信息加密等方面进行完善考虑,在网络架构上根据功能划分相应的区 域,使用如防火墙、入侵防御、加密设备对信息过滤、隔离、数据加密等...
为了在海量信息中找到对特定用户有价值的内容,系统可能需要分析用户的行为、偏好和社交网络关系,通过协同过滤、基于内容的推荐或混合推荐策略,提供个性化信息。 再者,可能涉及数据挖掘和自然语言处理技术。数据...
PGP(Pretty Good Privacy)是一种混合加密算法, 由对称加密算法(IDEA)、非对称加密算法(RSA)、单向散列算法和随机数产生器组成。PGP 工作原理包括认证算法、加密算法和保密算法。 认证算法的过程是:发送方...
- **BitTorrent**:尽管BitTorrent通常被认为是混合型P2P网络,但在其早期版本中,也采用了类似无结构P2P网络的查询机制。BitTorrent通过引入跟踪器(Tracker)来优化查询过程,提高了资源定位的效率。 - **Freenet*...
- 文本文件也可以通过加密方式进行传输。 #### 6. 服务端消息暂存机制 - **消息暂存**: - 服务端具备消息暂存功能。 - 当客户端暂时离线时,服务端可以暂存其消息直到重新上线。 #### 7. 接口实现方式 - **...
本方案在蓝牙5.0网络的基础上,提出了端到端的加密传输模式,并且融合了NTRU和AES两种加密算法,以确保数据传输的安全性。方案包括以下几个关键步骤: 1. 数字证书的生成与分发 - 每个车载单元(OBU)和路测单元...