加密技术可以分为对称与非对称两种.
对称加密,解密,即加密与解密用的是同一把秘钥,常用的对称加密技术有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对称加密,解密
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.OutputStream;
- importjava.security.InvalidKeyException;
- importjava.security.Key;
- importjava.security.NoSuchAlgorithmException;
- importjava.security.SecureRandom;
- importjavax.crypto.BadPaddingException;
- importjavax.crypto.Cipher;
- importjavax.crypto.IllegalBlockSizeException;
- importjavax.crypto.KeyGenerator;
- importjavax.crypto.NoSuchPaddingException;
- importjavax.crypto.ShortBufferException;
- publicclassAES{
- privateKeykey;
- /**
- *生成AES对称秘钥
- *@throwsNoSuchAlgorithmException
- */
- publicvoidgenerateKey()throwsNoSuchAlgorithmException{
- KeyGeneratorkeygen=KeyGenerator.getInstance("AES");
- SecureRandomrandom=newSecureRandom();
- keygen.init(random);
- this.key=keygen.generateKey();
- }
- /**
- *加密
- *@paramin
- *@paramout
- *@throwsInvalidKeyException
- *@throwsShortBufferException
- *@throwsIllegalBlockSizeException
- *@throwsBadPaddingException
- *@throwsNoSuchAlgorithmException
- *@throwsNoSuchPaddingException
- *@throwsIOException
- */
- publicvoidencrypt(InputStreamin,OutputStreamout)throwsInvalidKeyException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,IOException{
- this.crypt(in,out,Cipher.ENCRYPT_MODE);
- }
- /**
- *解密
- *@paramin
- *@paramout
- *@throwsInvalidKeyException
- *@throwsShortBufferException
- *@throwsIllegalBlockSizeException
- *@throwsBadPaddingException
- *@throwsNoSuchAlgorithmException
- *@throwsNoSuchPaddingException
- *@throwsIOException
- */
- publicvoiddecrypt(InputStreamin,OutputStreamout)throwsInvalidKeyException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,IOException{
- this.crypt(in,out,Cipher.DECRYPT_MODE);
- }
- /**
- *实际的加密解密过程
- *@paramin
- *@paramout
- *@parammode
- *@throwsIOException
- *@throwsShortBufferException
- *@throwsIllegalBlockSizeException
- *@throwsBadPaddingException
- *@throwsNoSuchAlgorithmException
- *@throwsNoSuchPaddingException
- *@throwsInvalidKeyException
- */
- publicvoidcrypt(InputStreamin,OutputStreamout,intmode)throwsIOException,ShortBufferException,IllegalBlockSizeException,BadPaddingException,NoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException{
- Ciphercipher=Cipher.getInstance("AES");
- cipher.init(mode,this.key);
- intblockSize=cipher.getBlockSize();
- intoutputSize=cipher.getOutputSize(blockSize);
- byte[]inBytes=newbyte[blockSize];
- byte[]outBytes=newbyte[outputSize];
- intinLength=0;
- booleanmore=true;
- while(more){
- inLength=in.read(inBytes);
- if(inLength==blockSize){
- intoutLength=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();
- }
- publicvoidsetKey(Keykey){
- this.key=key;
- }
- publicKeygetKey(){
- returnkey;
- }
- }
RSA非对称加密,解密对称秘钥
- publicclassRSA{
- publicstaticfinalintKEYSIZE=512;
- privateKeyPairkeyPair;
- privateKeypublicKey;
- privateKeyprivateKey;
- /**
- *生成秘钥对
- *@return
- *@throwsNoSuchAlgorithmException
- */
- publicKeyPairgenerateKeyPair()throwsNoSuchAlgorithmException{
- KeyPairGeneratorpairgen=KeyPairGenerator.getInstance("RSA");
- SecureRandomrandom=newSecureRandom();
- pairgen.initialize(RSA.KEYSIZE,random);
- this.keyPair=pairgen.generateKeyPair();
- returnthis.keyPair;
- }
- /**
- *加密秘钥
- *@paramkey
- *@return
- *@throwsNoSuchAlgorithmException
- *@throwsNoSuchPaddingException
- *@throwsInvalidKeyException
- *@throwsIllegalBlockSizeException
- */
- publicbyte[]wrapKey(Keykey)throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException{
- Ciphercipher=Cipher.getInstance("RSA");
- cipher.init(Cipher.WRAP_MODE,this.privateKey);
- byte[]wrappedKey=cipher.wrap(key);
- returnwrappedKey;
- }
- /**
- *解密秘钥
- *@paramwrapedKeyBytes
- *@return
- *@throwsNoSuchAlgorithmException
- *@throwsNoSuchPaddingException
- *@throwsInvalidKeyException
- */
- publicKeyunwrapKey(byte[]wrapedKeyBytes)throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException{
- Ciphercipher=Cipher.getInstance("RSA");
- cipher.init(Cipher.UNWRAP_MODE,this.publicKey);
- Keykey=cipher.unwrap(wrapedKeyBytes,"AES",Cipher.SECRET_KEY);
- returnkey;
- }
- publicKeygetPublicKey(){
- returnpublicKey;
- }
- publicvoidsetPublicKey(KeypublicKey){
- this.publicKey=publicKey;
- }
- publicKeygetPrivateKey(){
- returnprivateKey;
- }
- publicvoidsetPrivateKey(KeyprivateKey){
- this.privateKey=privateKey;
- }
- }
本文详细解释了加密技术中对称与非对称两种方式的区别,特别是非对称加密技术如何解决秘钥管理问题,并通过Java实现展示了实际应用。同时,介绍了将对称加密与非对称加密结合使用的高效方法。

200

被折叠的 条评论
为什么被折叠?



