公鑰,私鑰和數字簽名這樣最好理解 (轉載)

轉自:https://www.cnblogs.com/shenkebky/p/8461841.html

原文地址

http://blog.csdn.net/tabactivity/article/details/49685319

原文內容

一、公鑰加密  假設一下,我找了兩個數字,一個是1,一個是2。我喜歡2這個數字,就保留起來,不告訴你們(私鑰),然後我告訴大家,1是我的公鑰。

我有一個文件,不能讓別人看,我就用1加密了。別人找到了這個文件,但是他不知道2就是解密的私鑰啊,所以他解不開,只有我可以用 數字2,就是我的私鑰,來解密。這樣我就可以保護數據了。

我的好朋友x用我的公鑰1加密了字符a,加密後成了b,放在網上。別人偷到了這個文件,但是別人解不開,因爲別人不知道2就是我的私鑰, 只有我才能解密,解密後就得到a。這樣,我們就可以傳送加密的數據了。

 

二、私鑰簽名 如果我用私鑰加密一段數據(當然只有我可以用私鑰加密,因爲只有我知道2是我的私鑰),結果所有的人都看到我的內容了,因爲他們都知 道我的公鑰是1,那麼這種加密有什麼用處呢?

但是我的好朋友x說有人冒充我給他發信。怎麼辦呢?我把我要發的信,內容是c,用我的私鑰2,加密,加密後的內容是d,發給x,再告訴他 解密看是不是c。他用我的公鑰1解密,發現果然是c。 這個時候,他會想到,能夠用我的公鑰解密的數據,必然是用我的私鑰加的密。只有我知道我得私鑰,因此他就可以確認確實是我發的東西。 這樣我們就能確認發送方身份了。這個過程叫做數字簽名。當然具體的過程要稍微複雜一些。用私鑰來加密數據,用途就是數字簽名

 

總結:公鑰和私鑰是成對的,它們互相解密。

公鑰加密,私鑰解密。

私鑰數字簽名,公鑰驗證。

 

舉例

比如有兩個用戶Alice和Bob,Alice想把一段明文通過雙鑰加密的技術發送給Bob,Bob有一對公鑰和私鑰,那麼加密解密的過程如下:

  1. Bob將他的公開密鑰傳送給Alice。
  2. Alice用Bob的公開密鑰加密她的消息,然後傳送給Bob。
  3. Bob用他的私人密鑰解密Alice的消息。

  上面的過程可以用下圖表示,Alice使用Bob的公鑰進行加密,Bob用自己的私鑰進行解密。

例子和圖出自《網絡安全基礎 應用與標準第二版》

 

RSA算法

RSA公鑰加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前爲止已知的所有密碼攻擊,已被ISO推薦爲公鑰數據加密標準。RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作爲加密密鑰。

 

  1. package cn.aizichan.utils.digest;  
  2.   
  3. import java.security.Key;  
  4. import java.security.KeyFactory;  
  5. import java.security.KeyPair;  
  6. import java.security.KeyPairGenerator;  
  7. import java.security.PrivateKey;  
  8. import java.security.PublicKey;  
  9. import java.security.interfaces.RSAPrivateKey;  
  10. import java.security.interfaces.RSAPublicKey;  
  11. import java.security.spec.PKCS8EncodedKeySpec;  
  12. import java.security.spec.X509EncodedKeySpec;  
  13. import java.util.HashMap;  
  14. import java.util.Map;  
  15.   
  16. import javax.crypto.Cipher;  
  17.   
  18. public class RSACoder {  
  19.     //非對稱密鑰算法    
  20.     public static final String KEY_ALGORITHM="RSA";    
  21.     /**  
  22.      * 密鑰長度,DH算法的默認密鑰長度是1024  
  23.      * 密鑰長度必須是64的倍數,在512到65536位之間  
  24.      * */    
  25.     private static final int KEY_SIZE=512;    
  26.     //公鑰    
  27.     private static final String PUBLIC_KEY="xiaoxiaorenzhe";    
  28.         
  29.     //私鑰    
  30.     private static final String PRIVATE_KEY="dadapangzi";    
  31.       
  32.     /**  
  33.      * 初始化密鑰對  
  34.      * @return Map 甲方密鑰的Map  
  35.      * */    
  36.     public static Map<String,Object> initKey() throws Exception{    
  37.         //實例化密鑰生成器    
  38.         KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM);    
  39.         //初始化密鑰生成器    
  40.         keyPairGenerator.initialize(KEY_SIZE);    
  41.         //生成密鑰對    
  42.         KeyPair keyPair=keyPairGenerator.generateKeyPair();   
  43.         //甲方公鑰    
  44.         RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();    
  45.         System.out.println("係數:"+publicKey.getModulus()+"  加密指數:"+publicKey.getPublicExponent());  
  46.         //甲方私鑰    
  47.         RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();   
  48.         System.out.println("係數:"+privateKey.getModulus()+"解密指數:"+privateKey.getPrivateExponent());  
  49.         //將密鑰存儲在map中    
  50.         Map<String,Object> keyMap=new HashMap<String,Object>();    
  51.         keyMap.put(PUBLIC_KEY, publicKey);    
  52.         keyMap.put(PRIVATE_KEY, privateKey);    
  53.         return keyMap;    
  54.             
  55.     }    
  56.       
  57.     /**  
  58.      * 私鑰加密  
  59.      * @param data待加密數據  
  60.      * @param key 密鑰  
  61.      * @return byte[] 加密數據  
  62.      * */    
  63.     public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{    
  64.             
  65.         //取得私鑰    
  66.         PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);    
  67.         KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);    
  68.         //生成私鑰    
  69.         PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);    
  70.         //數據加密    
  71.         Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());    
  72.         cipher.init(Cipher.ENCRYPT_MODE, privateKey);    
  73.         return cipher.doFinal(data);    
  74.     }    
  75.       
  76.     /**  
  77.      * 公鑰加密  
  78.      * @param data待加密數據  
  79.      * @param key 密鑰  
  80.      * @return byte[] 加密數據  
  81.      * */    
  82.     public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{    
  83.             
  84.         //實例化密鑰工廠    
  85.         KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);    
  86.         //初始化公鑰    
  87.         //密鑰材料轉換    
  88.         X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);    
  89.         //產生公鑰    
  90.         PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);    
  91.             
  92.         //數據加密    
  93.         Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());    
  94.         cipher.init(Cipher.ENCRYPT_MODE, pubKey);    
  95.         return cipher.doFinal(data);    
  96.     }    
  97.     /**  
  98.      * 私鑰解密  
  99.      * @param data 待解密數據  
  100.      * @param key 密鑰  
  101.      * @return byte[] 解密數據  
  102.      * */    
  103.     public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{    
  104.         //取得私鑰    
  105.         PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);    
  106.         KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);    
  107.         //生成私鑰    
  108.         PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);    
  109.         //數據解密    
  110.         Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());    
  111.         cipher.init(Cipher.DECRYPT_MODE, privateKey);    
  112.         return cipher.doFinal(data);    
  113.     }    
  114.       
  115.     /**  
  116.      * 公鑰解密  
  117.      * @param data 待解密數據  
  118.      * @param key 密鑰  
  119.      * @return byte[] 解密數據  
  120.      * */    
  121.     public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{    
  122.             
  123.         //實例化密鑰工廠    
  124.         KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);    
  125.         //初始化公鑰    
  126.         //密鑰材料轉換    
  127.         X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);    
  128.         //產生公鑰    
  129.         PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);    
  130.         //數據解密    
  131.         Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());    
  132.         cipher.init(Cipher.DECRYPT_MODE, pubKey);    
  133.         return cipher.doFinal(data);    
  134.     }    
  135.       
  136.     /**  
  137.      * 取得私鑰  
  138.      * @param keyMap 密鑰map  
  139.      * @return byte[] 私鑰  
  140.      * */    
  141.     public static byte[] getPrivateKey(Map<String,Object> keyMap){    
  142.         Key key=(Key)keyMap.get(PRIVATE_KEY);    
  143.         return key.getEncoded();    
  144.     }    
  145.     /**  
  146.      * 取得公鑰  
  147.      * @param keyMap 密鑰map  
  148.      * @return byte[] 公鑰  
  149.      * */    
  150.     public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception{    
  151.         Key key=(Key) keyMap.get(PUBLIC_KEY);   
  152.         return key.getEncoded();    
  153.     }    
  154.     /**  
  155.      * @param args  
  156.      * @throws Exception   
  157.      */    
  158.     public static void main(String[] args) throws Exception {    
  159.         //初始化密鑰    
  160.         //生成密鑰對    
  161.         Map<String,Object> keyMap=RSACoder.initKey();    
  162.         //公鑰    
  163.         byte[] publicKey=RSACoder.getPublicKey(keyMap);  
  164.         //byte[] publicKey = b;  
  165.         //私鑰    
  166.         byte[] privateKey=RSACoder.getPrivateKey(keyMap);    
  167.         System.out.println("公鑰:"+Base64.encode(publicKey));         
  168.         System.out.println("私鑰:"+Base64.encode(privateKey));    
  169.             
  170.         System.out.println("================密鑰對構造完畢,甲方將公鑰公佈給乙方,開始進行加密數據的傳輸=============");    
  171.         String str="aattaggcctegthththfef/aat.mp4";    
  172.         System.out.println("===========甲方向乙方發送加密數據==============");    
  173.         System.out.println("原文:"+str);    
  174.         //甲方進行數據的加密    
  175.         byte[] code1=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);  
  176.         System.out.println("甲方 使用乙方公鑰加密後的數據:"+Base64.encode(code1));    
  177.         System.out.println("===========乙方使用甲方提供的公鑰對數據進行解密==============");    
  178.         //乙方進行數據的解密    
  179.         //byte[] decode1=RSACoder.decryptByPublicKey(code1, publicKey);    
  180.         byte[] decode1=RSACoder.decryptByPrivateKey(code1, privateKey);    
  181.         System.out.println("乙方解密後的數據:"+new String(decode1)+"");    
  182.             
  183.         System.out.println("===========反向進行操作,乙方向甲方發送數據==============");    
  184.             
  185.         str="乙方向甲方發送數據RSA算法";    
  186.             
  187.         System.out.println("原文:"+str);    
  188.             
  189.         //乙方使用公鑰對數據進行加密    
  190.         byte[] code2=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);    
  191.         System.out.println("===========乙方使用公鑰對數據進行加密==============");    
  192.         System.out.println("加密後的數據:"+Base64.encode(code2));    
  193.             
  194.         System.out.println("=============乙方將數據傳送給甲方======================");    
  195.         System.out.println("===========甲方使用私鑰對數據進行解密==============");    
  196.             
  197.         //甲方使用私鑰對數據進行解密    
  198.         byte[] decode2=RSACoder.decryptByPrivateKey(code2, privateKey);    
  199.             
  200.         System.out.println("甲方解密後的數據:"+new String(decode2));   
  201.           
  202.           
  203.     }    
  204. }  
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章