[size=medium]公钥是与私钥算法一起使用的密钥对的非秘密一半。公钥通常用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据。公钥和私钥是通过一种算法得到的一个密钥对(即一个公钥和一个私钥)其中的一个向外界公开,称为公钥;另一个自己保留,称为私钥。通过这种算法得到的密钥对能保证在世界范围内是唯一的。使用这个密钥对的时候,如果用其中一个密钥加密一段数据,必须用另一个密钥解密。比如用公钥加密数据就必须用私钥解密,如果用私钥加密也必须用公钥解密,否则解密将不会成功。


1976年。当时在美国斯坦福大学的迪菲(Diffie)和赫尔曼(Hellman)两人提出了公开密钥密码的新思想(论文"New Direction in Cryptography"),不仅加密算法本身可以公开,甚至加密用的密钥也可以公开。但这并不意味着保密程度的降低。因为如果加密密钥和解密密钥不一样。而将解密密钥保密就可以。这就是著名的公钥密码体制。也称作[b]非对称密码体制[/b]。不同于对称性的 密码学, 在于其加密钥匙只适用于单一用户。


一把私有的钥匙,仅有用户才拥有。
一把公开的钥匙,可公开发行配送,只要有要求即取得。
每支钥匙产生一个被使用来改变属性的功能。私有的钥匙产生一个私有改变属性的功能,而公开的钥匙 产生一个 公开改变属性的功能。这些功能是反向相关的,例如,如果一个功能是用来加密消息,另外一个功能则被用来解密消息。不论此改变属性功能的次序为何皆不重要。公开的钥匙系统的优势是两个用户能够安全的沟通而不需交换秘密钥匙。例如,假设一个送信者需要传送一个信息给一个收信者,而信息的秘密性是必要的, 送信者以收信者的公开的钥匙来加密,而仅有收信者的私有的钥匙能够对此信息解密。公开的钥匙密码学是非常适合于提供认证,完整和不能否认的服务, 所有的这些服务即是我们所知的数字签名


除了加密外,公开钥匙密码学最显著的成就是实现了数字签名。数字签名,顾名思义,就是是普通签章的数字化,他们的特性都是某人可以轻易制造签章,但他人却难以仿冒。数字签名可以永久地与被签署信息结合,无法自信息上移除。数字签名大致包含两个算法:一个是签署,使用私密钥匙处理信息或信息的哈希值而产生签章;另一个是验证,使用公开钥匙验证签章的真实性。RSA和DSA是两种最流行的数字签名机制。数字签名是公开钥匙基础建设(public key infranstructures, PKI)以及许多网络安全机制(SSL/TLS, VPNs等)的基础。
公开钥匙算法大多基于计算复杂度上的难题,通常来自于数论。例如,RSA源于整数因子分解问题;DSA源于离散对数问题。发展快速的椭圆曲线密码学则基于和椭圆曲线相关的数学难题,与离散对数相当。由于这些底层的问题多涉及模数乘法或指数运算,相对于分组密码需要更多计算资源。因此,公开钥匙系统通常是复合式的,内含一个高效率的对称钥匙算法,用以加密信息,再以公开钥匙加密对称钥匙系统所使用的钥匙,以增进效率。

java中的使用RSA算法进行公钥加密私钥解密
分类: 数字签名 2008-01-01 23:19 8439人阅读 评论(9) 收藏 举报
加密算法javabytestring解密
一个比较简单的实现:一个三个类KeyGenerater生成公钥私钥对,Signaturer类使用私钥签名,SignProvider用公钥验证。公钥和私钥使用Base64加密Base64这个类也在博客里面

public class KeyGenerater { 

 private byte[] priKey; 

 private byte[] pubKey; 


 public void generater() { 

 try { 

 java.security.KeyPairGenerator keygen = java.security.KeyPairGenerator 

 .getInstance("RSA"); 

 SecureRandom secrand = new SecureRandom(); 

 secrand.setSeed("syj".getBytes()); // 初始化随机产生器 

 keygen.initialize(1024, secrand); 

 KeyPair keys = keygen.genKeyPair(); 


 PublicKey pubkey = keys.getPublic(); 

 PrivateKey prikey = keys.getPrivate(); 


 pubKey = Base64.encodeToByte(pubkey.getEncoded()); 

 priKey = Base64.encodeToByte(prikey.getEncoded()); 


 System.out.println("pubKey = " + new String(pubKey)); 

 System.out.println("priKey = " + new String(priKey)); 

 } catch (java.lang.Exception e) { 

 System.out.println("生成密钥对失败"); 

 e.printStackTrace(); 

 } 

 } 


 public byte[] getPriKey() { 

 return priKey; 

 } 


 public byte[] getPubKey() { 

 return pubKey; 

 } 

} 




public class Signaturer { 

 /** 

 * 

 * Description:数字签名 

 * 

 * @param priKeyText 

 * @param plainText 

 * @return 

 * @author 孙钰佳 

 * @since:2007-12-27 上午10:51:48 

 */ 

 public static byte[] sign(byte[] priKeyText, String plainText) { 

 try { 

 PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64 

 .decode(priKeyText)); 

 KeyFactory keyf = KeyFactory.getInstance("RSA"); 

 PrivateKey prikey = keyf.generatePrivate(priPKCS8); 


 // 用私钥对信息生成数字签名 

 java.security.Signature signet = java.security.Signature 

 .getInstance("MD5withRSA"); 

 signet.initSign(prikey); 

 signet.update(plainText.getBytes()); 

 byte[] signed = Base64.encodeToByte(signet.sign()); 

 return signed; 

 } catch (java.lang.Exception e) { 

 System.out.println("签名失败"); 

 e.printStackTrace(); 

 } 

 return null; 

 } 

} 


public class SignProvider { 

 private SignProvider() { 


 } 


 /** 

 * 

 * Description:校验数字签名,此方法不会抛出任务异常,成功返回true,失败返回false,要求全部参数不能为空 

 * 

 * @param pubKeyText 

 * 公钥,base64编码 

 * @param plainText 

 * 明文 

 * @param signTest 

 * 数字签名的密文,base64编码 

 * @return 校验成功返回true 失败返回false 

 * @author 孙钰佳 

 * @since:2007-12-27 上午09:33:55 

 */ 

 public static boolean verify(byte[] pubKeyText, String plainText, 

 byte[] signText) { 

 try { 

 // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象 

 java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( 

 Base64.decode(pubKeyText)); 

 // RSA对称加密算法 

 java.security.KeyFactory keyFactory = java.security.KeyFactory 

 .getInstance("RSA"); 

 // 取公钥匙对象 

 java.security.PublicKey pubKey = keyFactory 

 .generatePublic(bobPubKeySpec); 

 // 解密由base64编码的数字签名 

 byte[] signed = Base64.decode(signText); 

 java.security.Signature signatureChecker = java.security.Signature 

 .getInstance("MD5withRSA"); 

 signatureChecker.initVerify(pubKey); 

 signatureChecker.update(plainText.getBytes()); 

 // 验证签名是否正常 

 if (signatureChecker.verify(signed)) 

 return true; 

 else 

 return false; 

 } catch (Throwable e) { 

 System.out.println("校验签名失败"); 

 e.printStackTrace(); 

 return false; 

 } 

 } 

} 


[/size]