Java对称与非对称加密解密,AES与RSA

本文详细解释了加密技术中对称与非对称两种方式的区别,特别是非对称加密技术如何解决秘钥管理问题,并通过Java实现展示了实际应用。同时,介绍了将对称加密与非对称加密结合使用的高效方法。

加密技术可以分为对称与非对称两种.

对称加密,解密,即加密与解密用的是同一把秘钥,常用的对称加密技术有DES,AES等

而非对称技术,加密与解密用的是不同的秘钥,常用的非对称加密技术有RSA等

为什么要有非对称加密,解密技术呢

假设这样一种场景A要发送一段消息给B,但是又不想以明文发送,所以就需要对消息进行加密.如果采用对称加密技术,那么加密与解密用的是同一把秘钥.除非B事先就知道A的秘钥,并且保存好.这样才可以解密A发来的消息.

由于对称技术只有一把秘钥,所以秘钥的管理是一个很麻烦的问题.而非对称技术的诞生就解决了这个问题.非对称加密与解密使用的是不同的秘钥,并且秘钥对是一一对应的,即用A的私钥加密的密文只有用A的公钥才能解密.

这样的话,每个人都有两把秘钥,私钥和公钥,私钥是只有自己才知道的,不能告诉别人,而公钥是公开的,大家都可以知道.这样,当A想要发送消息给B的时候,只需要用B的公钥对消息进行加密就可以了,由于B的私钥只有B才拥有,所以A用B的公钥加密的消息只有B才能解开.而B想更换自己的秘要时也很方便,只须把公钥告诉大家就可以了.

那么,既然非对称加密如此之好,对称加密就没有存在的必要了啊,其实不然,由于非对称加密算法的开销很大,所以如果直接以非对称技术来加密发送的消息效率会很差.那么怎么办呢?解决的办法也很简单,就是把对称加密技术与非对称加密技术结合起来使用.

还是这个例子:A要发送一个消息给B.

一,A先生成一个对称秘钥,这个秘钥可以是随机生成的,

二,A用B的公钥加密第一步生成的这个对称秘钥

三,A把加密过的对称秘钥发给B

四,A用第一步生成的这个对称秘钥加密实际要发的消息

五,A把用对称秘钥加密的消息发给B

对于B

他先收到A发来的对称秘钥,这个秘钥是用B的公钥加密过的,所以B需要用自己的私钥来解密这个秘钥

然后B又收到A发来的密文,这时候用刚才解密出来的秘钥来解密密文

这样子的整个过程既保证了安全,又保证了效率.

接下来是Java实现:

我这个Java实现使用的是AES的对称加密和RSA的非对称加密(DES的对称加密实现方法和AES的是一样的,但是由于DES算法本身有缺陷,容易被破解,所以现在多用其升级版AES对称加密)

AES对称加密,解密

Java代码 收藏代码
  1. importjava.io.IOException;
  2. importjava.io.InputStream;
  3. importjava.io.OutputStream;
  4. importjava.security.InvalidKeyException;
  5. importjava.security.Key;
  6. importjava.security.NoSuchAlgorithmException;
  7. importjava.security.SecureRandom;
  8. importjavax.crypto.BadPaddingException;
  9. importjavax.crypto.Cipher;
  10. importjavax.crypto.IllegalBlockSizeException;
  11. importjavax.crypto.KeyGenerator;
  12. importjavax.crypto.NoSuchPaddingException;
  13. importjavax.crypto.ShortBufferException;
  14. publicclassAES{
  15. privateKeykey;
  16. /**
  17. *生成AES对称秘钥
  18. *@throwsNoSuchAlgorithmException
  19. */
  20. publicvoidgenerateKey()throwsNoSuchAlgorithmException{
  21. KeyGeneratorkeygen=KeyGenerator.getInstance("AES");
  22. SecureRandomrandom=newSecureRandom();
  23. keygen.init(random);
  24. this.key=keygen.generateKey();
  25. }
  26. /**
  27. *加密
  28. *@paramin
  29. *@paramout
  30. *@throwsInvalidKeyException
  31. *@throwsShortBufferException
  32. *@throwsIllegalBlockSizeException
  33. *@throwsBadPaddingException
  34. *@throwsNoSuchAlgorithmException
  35. *@throwsNoSuchPaddingException
  36. *@throwsIOException
  37. */
  38. publicvoidencrypt(InputStreamin,OutputStreamout)throwsInvalidKeyException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,IOException{
  39. this.crypt(in,out,Cipher.ENCRYPT_MODE);
  40. }
  41. /**
  42. *解密
  43. *@paramin
  44. *@paramout
  45. *@throwsInvalidKeyException
  46. *@throwsShortBufferException
  47. *@throwsIllegalBlockSizeException
  48. *@throwsBadPaddingException
  49. *@throwsNoSuchAlgorithmException
  50. *@throwsNoSuchPaddingException
  51. *@throwsIOException
  52. */
  53. publicvoiddecrypt(InputStreamin,OutputStreamout)throwsInvalidKeyException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,IOException{
  54. this.crypt(in,out,Cipher.DECRYPT_MODE);
  55. }
  56. /**
  57. *实际的加密解密过程
  58. *@paramin
  59. *@paramout
  60. *@parammode
  61. *@throwsIOException
  62. *@throwsShortBufferException
  63. *@throwsIllegalBlockSizeException
  64. *@throwsBadPaddingException
  65. *@throwsNoSuchAlgorithmException
  66. *@throwsNoSuchPaddingException
  67. *@throwsInvalidKeyException
  68. */
  69. publicvoidcrypt(InputStreamin,OutputStreamout,intmode)throwsIOException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException{
  70. Ciphercipher=Cipher.getInstance("AES");
  71. cipher.init(mode,this.key);
  72. intblockSize=cipher.getBlockSize();
  73. intoutputSize=cipher.getOutputSize(blockSize);
  74. byte[]inBytes=newbyte[blockSize];
  75. byte[]outBytes=newbyte[outputSize];
  76. intinLength=0;
  77. booleanmore=true;
  78. while(more){
  79. inLength=in.read(inBytes);
  80. if(inLength==blockSize){
  81. intoutLength=cipher.update(inBytes,0,blockSize,outBytes);
  82. out.write(outBytes,0,outLength);
  83. }else{
  84. more=false;
  85. }
  86. }
  87. if(inLength>0)
  88. outBytes=cipher.doFinal(inBytes,0,inLength);
  89. else
  90. outBytes=cipher.doFinal();
  91. out.write(outBytes);
  92. out.flush();
  93. }
  94. publicvoidsetKey(Keykey){
  95. this.key=key;
  96. }
  97. publicKeygetKey(){
  98. returnkey;
  99. }
  100. }

RSA非对称加密,解密对称秘钥

Java代码 收藏代码
  1. publicclassRSA{
  2. publicstaticfinalintKEYSIZE=512;
  3. privateKeyPairkeyPair;
  4. privateKeypublicKey;
  5. privateKeyprivateKey;
  6. /**
  7. *生成秘钥对
  8. *@return
  9. *@throwsNoSuchAlgorithmException
  10. */
  11. publicKeyPairgenerateKeyPair()throwsNoSuchAlgorithmException{
  12. KeyPairGeneratorpairgen=KeyPairGenerator.getInstance("RSA");
  13. SecureRandomrandom=newSecureRandom();
  14. pairgen.initialize(RSA.KEYSIZE,random);
  15. this.keyPair=pairgen.generateKeyPair();
  16. returnthis.keyPair;
  17. }
  18. /**
  19. *加密秘钥
  20. *@paramkey
  21. *@return
  22. *@throwsNoSuchAlgorithmException
  23. *@throwsNoSuchPaddingException
  24. *@throwsInvalidKeyException
  25. *@throwsIllegalBlockSizeException
  26. */
  27. publicbyte[]wrapKey(Keykey)throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException{
  28. Ciphercipher=Cipher.getInstance("RSA");
  29. cipher.init(Cipher.WRAP_MODE,this.privateKey);
  30. byte[]wrappedKey=cipher.wrap(key);
  31. returnwrappedKey;
  32. }
  33. /**
  34. *解密秘钥
  35. *@paramwrapedKeyBytes
  36. *@return
  37. *@throwsNoSuchAlgorithmException
  38. *@throwsNoSuchPaddingException
  39. *@throwsInvalidKeyException
  40. */
  41. publicKeyunwrapKey(byte[]wrapedKeyBytes)throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException{
  42. Ciphercipher=Cipher.getInstance("RSA");
  43. cipher.init(Cipher.UNWRAP_MODE,this.publicKey);
  44. Keykey=cipher.unwrap(wrapedKeyBytes,"AES",Cipher.SECRET_KEY);
  45. returnkey;
  46. }
  47. publicKeygetPublicKey(){
  48. returnpublicKey;
  49. }
  50. publicvoidsetPublicKey(KeypublicKey){
  51. this.publicKey=publicKey;
  52. }
  53. publicKeygetPrivateKey(){
  54. returnprivateKey;
  55. }
  56. publicvoidsetPrivateKey(KeyprivateKey){
  57. this.privateKey=privateKey;
  58. }
  59. }
转自:http://redstarofsleep.iteye.com/blog/1171282
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值