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

对称加密,解密,即加密与解密用的是同一把秘钥,常用的对称加密技术有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对称加密,解密

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.io.OutputStream;
  4. import java.security.InvalidKeyException;
  5. import java.security.Key;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.security.SecureRandom;
  8. import javax.crypto.BadPaddingException;
  9. import javax.crypto.Cipher;
  10. import javax.crypto.IllegalBlockSizeException;
  11. import javax.crypto.KeyGenerator;
  12. import javax.crypto.NoSuchPaddingException;
  13. import javax.crypto.ShortBufferException;
  14. public class AES {
  15. private Key key;
  16. /**
  17. * 生成AES对称秘钥
  18. * @throws NoSuchAlgorithmException
  19. */
  20. public void generateKey() throws NoSuchAlgorithmException {
  21. KeyGenerator keygen = KeyGenerator.getInstance("AES");
  22. SecureRandom random = new SecureRandom();
  23. keygen.init(random);
  24. this.key = keygen.generateKey();
  25. }
  26. /**
  27. * 加密
  28. * @param in
  29. * @param out
  30. * @throws InvalidKeyException
  31. * @throws ShortBufferException
  32. * @throws IllegalBlockSizeException
  33. * @throws BadPaddingException
  34. * @throws NoSuchAlgorithmException
  35. * @throws NoSuchPaddingException
  36. * @throws IOException
  37. */
  38. public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
  39. this.crypt(in, out, Cipher.ENCRYPT_MODE);
  40. }
  41. /**
  42. * 解密
  43. * @param in
  44. * @param out
  45. * @throws InvalidKeyException
  46. * @throws ShortBufferException
  47. * @throws IllegalBlockSizeException
  48. * @throws BadPaddingException
  49. * @throws NoSuchAlgorithmException
  50. * @throws NoSuchPaddingException
  51. * @throws IOException
  52. */
  53. public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
  54. this.crypt(in, out, Cipher.DECRYPT_MODE);
  55. }
  56. /**
  57. * 实际的加密解密过程
  58. * @param in
  59. * @param out
  60. * @param mode
  61. * @throws IOException
  62. * @throws ShortBufferException
  63. * @throws IllegalBlockSizeException
  64. * @throws BadPaddingException
  65. * @throws NoSuchAlgorithmException
  66. * @throws NoSuchPaddingException
  67. * @throws InvalidKeyException
  68. */
  69. public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
  70. Cipher cipher = Cipher.getInstance("AES");
  71. cipher.init(mode, this.key);
  72. int blockSize = cipher.getBlockSize();
  73. int outputSize = cipher.getOutputSize(blockSize);
  74. byte[] inBytes = new byte[blockSize];
  75. byte[] outBytes = new byte[outputSize];
  76. int inLength = 0;
  77. boolean more = true;
  78. while (more) {
  79. inLength = in.read(inBytes);
  80. if (inLength == blockSize) {
  81. int outLength = 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. public void setKey(Key key) {
  95. this.key = key;
  96. }
  97. public Key getKey() {
  98. return key;
  99. }
  100. }

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

  1. public class RSA {
  2. public static final int KEYSIZE = 512;
  3. private KeyPair keyPair;
  4. private Key publicKey;
  5. private Key privateKey;
  6. /**
  7. * 生成秘钥对
  8. * @return
  9. * @throws NoSuchAlgorithmException
  10. */
  11. public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
  12. KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
  13. SecureRandom random = new SecureRandom();
  14. pairgen.initialize(RSA.KEYSIZE, random);
  15. this.keyPair = pairgen.generateKeyPair();
  16. return this.keyPair;
  17. }
  18. /**
  19. * 加密秘钥
  20. * @param key
  21. * @return
  22. * @throws NoSuchAlgorithmException
  23. * @throws NoSuchPaddingException
  24. * @throws InvalidKeyException
  25. * @throws IllegalBlockSizeException
  26. */
  27. public byte[] wrapKey(Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException {
  28. Cipher cipher = Cipher.getInstance("RSA");
  29. cipher.init(Cipher.WRAP_MODE, this.privateKey);
  30. byte[] wrappedKey = cipher.wrap(key);
  31. return wrappedKey;
  32. }
  33. /**
  34. * 解密秘钥
  35. * @param wrapedKeyBytes
  36. * @return
  37. * @throws NoSuchAlgorithmException
  38. * @throws NoSuchPaddingException
  39. * @throws InvalidKeyException
  40. */
  41. public Key unwrapKey(byte[] wrapedKeyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
  42. Cipher cipher = Cipher.getInstance("RSA");
  43. cipher.init(Cipher.UNWRAP_MODE, this.publicKey);
  44. Key key = cipher.unwrap(wrapedKeyBytes, "AES", Cipher.SECRET_KEY);
  45. return key;
  46. }
  47. public Key getPublicKey() {
  48. return publicKey;
  49. }
  50. public void setPublicKey(Key publicKey) {
  51. this.publicKey = publicKey;
  52. }
  53. public Key getPrivateKey() {
  54. return privateKey;
  55. }
  56. public void setPrivateKey(Key privateKey) {
  57. this.privateKey = privateKey;
  58. }
  59. }

Java对称与非对称加密解密,AES与RSA的更多相关文章

  1. C#.NET中对称和非对称加密、解密方法汇总--亲测可用

    C#.NET中对称和非对称加密.解密方法汇总--亲测可用   在安全性要求比较高的系统中都会涉及到数据的加密.解密..NET为我们封装了常用的加密算法,例如:MD5,DES,RSA等.有可逆加密,也有 ...

  2. 第十四章 调试及安全性(In .net4.5) 之 对称及非对称加密

    1. 概述 本章内容包括:对称及非对称加密算法..net中的加密类.使用哈希操作.创建和管理签名认证.代码访问权限 和 加密字符串. 2. 主要内容 2.1 使用对称和非对称加密 ① 对称加密:使用同 ...

  3. 使用python进行加密解密AES算法

    使用python进行加密解密AES算法-代码分享-PYTHON开发者社区-pythoner.org 使用python进行加密解密AES算法 TY 发布于 2011-09-26 21:36:53,分类: ...

  4. SM4加密算法实现Java和C#相互加密解密

    SM4加密算法实现Java和C#相互加密解密 近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多 ...

  5. Java语言实现 Base64 加密 & 解密

    Java语言实现 Base64 加密 & 解密 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法. Base64 ...

  6. 使用java实现对称加密解密(AES),非对称加密解密(RSA)

    对称加密:双方采用同样的秘钥进行加密和解密.特点是速度快,但是安全性没有非对称加密高 非对称加密:接收方生成的公有秘钥公布给发送方,发送方使用该公有秘钥加密之后,发送给接收方,然后接收方使用私有秘钥解 ...

  7. AES加密解密——AES在JavaWeb项目中前台JS加密,后台Java解密的使用

    一:前言 在软件开发中,经常要对数据进行传输,数据在传输的过程中可能被拦截,被监听,所以在传输数据的时候使用数据的原始内容进行传输的话,安全隐患是非常大的.因此就要对需要传输的数据进行在客户端进行加密 ...

  8. java编写非对称加密,解密,公钥加密,私钥解密,RSA,rsa

    非对称加密已经被评为加密标准,主要包含(公钥加密私钥解密,或者私钥加密公钥解密)本文主要讲解的是如何用java生成 公钥和私钥并且 进行字符串加密 和字符串解密    //如需要代码copy如下 im ...

  9. 加密解密 AES RSA MD5 SHA

    加密解密: 对称加密:加密和解密相同秘钥.常见算法:AES, XTEA, 3DES. 非对称加密: 公钥加密 私钥加密. 加密和解密秘钥不同.常见算法:RSA OpenSSL> genrsa - ...

随机推荐

  1. npm使用入门(package.json)

    npm使用入门 crazygit 关注 2017.03.10 18:31 字数 1773 阅读 1617评论 0喜欢 10 NPM是什么 npm npm makes it easy for JavaS ...

  2. eclipse 新项目导入到tfs 步骤

    为了下次导入项目 不动脑子,写下此步骤.... 1.右键要导入的项目>> share project(如果有这项就点它,然后 进入 分享至你的tfs服务器即可) 1.右键要导入的项目> ...

  3. Python 示例 饮水记录

    因为每天都需要喝水  这是非常重要的 目录结构: ├─bin│ │ start.py│ ││ └─__pycache__│ start.cpython-36.pyc│├─core│ │ src.py│ ...

  4. mongodb 怎样检测 安装成功 以及mongodb的一些增删改查命令

    mongodb 主页 http://www.mongodb.org/ 1.先在网上下载一个mongodb的安装包,再打开cmd命令,找到你装mongodb的文件的路径,进到mongodb的文件下的li ...

  5. Spark学习笔记4:数据读取与保存

    Spark对很多种文件格式的读取和保存方式都很简单.Spark会根据文件扩展名选择对应的处理方式. Spark支持的一些常见文件格式如下: 文本文件 使用文件路径作为参数调用SparkContext中 ...

  6. Docker-compose 在up之后,各个子服务容器的hosts文件中不能找到父服务的域名

    使用命令查看docker当前建立的网络: docker network ls 发现docker-compose up确实建立了网络xx_default 使用命令查看该网络详细信息: docker in ...

  7. flask中的蓝图与红图

    内容: 1.flask中的蓝图 2.flask子域名实现 3.flask中的红图 1.flask中的蓝图 一个大型项目中视图比较多,如果仅仅是写在app.py中不方便管理,蓝图就可以做到分功能分目录结 ...

  8. 代码: 日期和时间 datepicker

    bootstrap 的相关的时间插件 http://www.bootcss.com/p/bootstrap-datetimepicker/ jquery ui的日期插件 http://www.w3cs ...

  9. WindowBrush

    m_Element.Fill = SystemColors.WindowBrush; BorderBrush="{x:Static SystemColors.WindowBrush}&quo ...

  10. leetcode210

    public class Solution { //test case [1,0] public int[] findOrder(int numCourses, int[][] prerequisit ...