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

对称加密,解密,即加密与解密用的是同一把秘钥,常用的对称加密技术有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.      
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;

public class AES {
	
	private Key key;
	
	/**
	 * 生成AES对称秘钥
	 * @throws NoSuchAlgorithmException
	 */
	public void generateKey() throws NoSuchAlgorithmException {
		KeyGenerator keygen = KeyGenerator.getInstance("AES");
		SecureRandom random = new SecureRandom();
		keygen.init(random);
		this.key = keygen.generateKey();
	}
	
	
	/**
	 * 加密
	 * @param in
	 * @param out
	 * @throws InvalidKeyException
	 * @throws ShortBufferException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws IOException
	 */
	public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
		this.crypt(in, out, Cipher.ENCRYPT_MODE);
	}
	
	/**
	 * 解密
	 * @param in
	 * @param out
	 * @throws InvalidKeyException
	 * @throws ShortBufferException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws IOException
	 */
	public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
		this.crypt(in, out, Cipher.DECRYPT_MODE);
	}

	/**
	 * 实际的加密解密过程
	 * @param in
	 * @param out
	 * @param mode
	 * @throws IOException
	 * @throws ShortBufferException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 */
	public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(mode, this.key);
		
		int blockSize = cipher.getBlockSize();
		int outputSize = cipher.getOutputSize(blockSize);
		byte[] inBytes = new byte[blockSize];
		byte[] outBytes = new byte[outputSize];
		
		int inLength = 0;
		boolean more = true;
		while (more) {
			inLength = in.read(inBytes);
			if (inLength == blockSize) {
				int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
				out.write(outBytes, 0, outLength);
			} else {
				more = false;
			}
		}
		if (inLength > 0)
			outBytes = cipher.doFinal(inBytes, 0, inLength);
		else
			outBytes = cipher.doFinal();
		out.write(outBytes);
		out.flush();
	}

	public void setKey(Key key) {
		this.key = key;
	}

	public Key getKey() {
		return key;
	}
	
}

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.      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值