zoukankan      html  css  js  c++  java
  • Java对称与非对称加密解密,AES与RSA

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

    对称加密,解密,即加密与解密用的是同一把秘钥,常用的对称加密技术有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. 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.   
    9. import javax.crypto.BadPaddingException;  
    10. import javax.crypto.Cipher;  
    11. import javax.crypto.IllegalBlockSizeException;  
    12. import javax.crypto.KeyGenerator;  
    13. import javax.crypto.NoSuchPaddingException;  
    14. import javax.crypto.ShortBufferException;  
    15.   
    16. public class AES {  
    17.       
    18.     private Key key;  
    19.       
    20.     /** 
    21.      * 生成AES对称秘钥 
    22.      * @throws NoSuchAlgorithmException 
    23.      */  
    24.     public void generateKey() throws NoSuchAlgorithmException {  
    25.         KeyGenerator keygen = KeyGenerator.getInstance("AES");  
    26.         SecureRandom random = new SecureRandom();  
    27.         keygen.init(random);  
    28.         this.key = keygen.generateKey();  
    29.     }  
    30.       
    31.       
    32.     /** 
    33.      * 加密 
    34.      * @param in 
    35.      * @param out 
    36.      * @throws InvalidKeyException 
    37.      * @throws ShortBufferException 
    38.      * @throws IllegalBlockSizeException 
    39.      * @throws BadPaddingException 
    40.      * @throws NoSuchAlgorithmException 
    41.      * @throws NoSuchPaddingException 
    42.      * @throws IOException 
    43.      */  
    44.     public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
    45.         this.crypt(in, out, Cipher.ENCRYPT_MODE);  
    46.     }  
    47.       
    48.     /** 
    49.      * 解密 
    50.      * @param in 
    51.      * @param out 
    52.      * @throws InvalidKeyException 
    53.      * @throws ShortBufferException 
    54.      * @throws IllegalBlockSizeException 
    55.      * @throws BadPaddingException 
    56.      * @throws NoSuchAlgorithmException 
    57.      * @throws NoSuchPaddingException 
    58.      * @throws IOException 
    59.      */  
    60.     public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {  
    61.         this.crypt(in, out, Cipher.DECRYPT_MODE);  
    62.     }  
    63.   
    64.     /** 
    65.      * 实际的加密解密过程 
    66.      * @param in 
    67.      * @param out 
    68.      * @param mode 
    69.      * @throws IOException 
    70.      * @throws ShortBufferException 
    71.      * @throws IllegalBlockSizeException 
    72.      * @throws BadPaddingException 
    73.      * @throws NoSuchAlgorithmException 
    74.      * @throws NoSuchPaddingException 
    75.      * @throws InvalidKeyException 
    76.      */  
    77.     public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {  
    78.         Cipher cipher = Cipher.getInstance("AES");  
    79.         cipher.init(mode, this.key);  
    80.           
    81.         int blockSize = cipher.getBlockSize();  
    82.         int outputSize = cipher.getOutputSize(blockSize);  
    83.         byte[] inBytes = new byte[blockSize];  
    84.         byte[] outBytes = new byte[outputSize];  
    85.           
    86.         int inLength = 0;  
    87.         boolean more = true;  
    88.         while (more) {  
    89.             inLength = in.read(inBytes);  
    90.             if (inLength == blockSize) {  
    91.                 int outLength = cipher.update(inBytes, 0, blockSize, outBytes);  
    92.                 out.write(outBytes, 0, outLength);  
    93.             } else {  
    94.                 more = false;  
    95.             }  
    96.         }  
    97.         if (inLength > 0)  
    98.             outBytes = cipher.doFinal(inBytes, 0, inLength);  
    99.         else  
    100.             outBytes = cipher.doFinal();  
    101.         out.write(outBytes);  
    102.         out.flush();  
    103.     }  
    104.   
    105.     public void setKey(Key key) {  
    106.         this.key = key;  
    107.     }  
    108.   
    109.     public Key getKey() {  
    110.         return key;  
    111.     }  
    112.       
    113. }  

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

    Java代码  收藏代码
    1. public class RSA {  
    2.   
    3.     public static final int KEYSIZE = 512;  
    4.       
    5.     private KeyPair keyPair;  
    6.     private Key publicKey;  
    7.     private Key privateKey;  
    8.       
    9.     /** 
    10.      * 生成秘钥对 
    11.      * @return 
    12.      * @throws NoSuchAlgorithmException 
    13.      */  
    14.     public KeyPair generateKeyPair() throws NoSuchAlgorithmException {  
    15.         KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");  
    16.         SecureRandom random = new SecureRandom();  
    17.         pairgen.initialize(RSA.KEYSIZE, random);  
    18.         this.keyPair = pairgen.generateKeyPair();  
    19.         return this.keyPair;  
    20.     }  
    21.   
    22.     /** 
    23.      * 加密秘钥 
    24.      * @param key 
    25.      * @return 
    26.      * @throws NoSuchAlgorithmException 
    27.      * @throws NoSuchPaddingException 
    28.      * @throws InvalidKeyException 
    29.      * @throws IllegalBlockSizeException 
    30.      */  
    31.     public byte[] wrapKey(Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException {  
    32.         Cipher cipher = Cipher.getInstance("RSA");  
    33.         cipher.init(Cipher.WRAP_MODE, this.privateKey);  
    34.         byte[] wrappedKey = cipher.wrap(key);  
    35.         return wrappedKey;  
    36.     }  
    37.       
    38.     /** 
    39.      * 解密秘钥 
    40.      * @param wrapedKeyBytes 
    41.      * @return 
    42.      * @throws NoSuchAlgorithmException 
    43.      * @throws NoSuchPaddingException 
    44.      * @throws InvalidKeyException 
    45.      */  
    46.     public Key unwrapKey(byte[] wrapedKeyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {  
    47.         Cipher cipher = Cipher.getInstance("RSA");  
    48.         cipher.init(Cipher.UNWRAP_MODE, this.publicKey);  
    49.         Key key = cipher.unwrap(wrapedKeyBytes, "AES", Cipher.SECRET_KEY);  
    50.         return key;  
    51.     }  
    52.   
    53.     public Key getPublicKey() {  
    54.         return publicKey;  
    55.     }  
    56.   
    57.     public void setPublicKey(Key publicKey) {  
    58.         this.publicKey = publicKey;  
    59.     }  
    60.   
    61.     public Key getPrivateKey() {  
    62.         return privateKey;  
    63.     }  
    64.   
    65.     public void setPrivateKey(Key privateKey) {  
    66.         this.privateKey = privateKey;  
    67.     }  
    68.       
    69. }  
  • 相关阅读:
    人生苦短_我用Python_javascript_var_function_简单笔记_001
    人生苦短_我用Python_logging日志操作_011
    人生苦短_我用Python_configparser/yaml对配置文件读取/写入操作_010
    人生苦短_我用Python_pymysql库对Mysql数据库操作_009
    人生苦短_我用Python_openpyxl库读取Excel文件数据_008
    人生苦短_我用Python_Try_Exception异常捕捉_007
    命令行下编译打包安卓apk
    构建微服务实验环境
    Docker的安全问题以及一些预防方案
    Go 微服务实践
  • 原文地址:https://www.cnblogs.com/jtlgb/p/6529821.html
Copyright © 2011-2022 走看看