加密 , 解密 。。。

加密算法有不少種:這裏只大約列舉幾例:java

1:消息摘要:(數字指紋):既對一個任意長度的一個數據塊進行計算,產生一個惟一指紋。MD5/SHA1
發送給其餘人你的信息和摘要,其餘人用相同的加密方法獲得摘要,最後進行比較摘要是否相同。

2:單匙密碼體制:DES:比較簡便高效,密鑰簡短,加解密速度快,破譯極其困難,但其安全性依賴於密匙的安全性。
DES(Data Encryption Standard)是發明最先的最普遍使用的分組對稱加密算法。DES算法的入口參數有三個:Key、Data、Mode。其中Key爲8個字節共64位,是DES算法的工做密鑰;Data也爲8個字節64位,是要被加密或被解密的數據;Mode爲DES的工做方式,有兩種:加密或解密

3:數字簽名:就是信息發送者用其私鑰對從所傳報文中提取出的特徵數據(或稱數字指紋)進行RSA算法操做,以保證發信人沒法抵賴曾發過該信息(即不可抵賴性),同時也確保信息報文在經簽名後末被篡改(即完整性)。當信息接收者收到報文後,就能夠用發送者的公鑰對數字簽名進行驗證。
表明:DSA

4:非對稱密匙密碼體制(公匙體系):加密密匙不一樣於解密密匙,加密密匙公之於衆,誰均可以使用,解密密匙只有解密人本身知道。表明:RSA算法

下面是對上面幾個例子進行的簡單實現:數組


Java代碼
  1. package test;  安全

  2. import java.io.FileInputStream;  框架

  3. import java.io.FileOutputStream;  dom

  4. import java.io.IOException;  ide

  5. import java.io.ObjectInputStream;  測試

  6. import java.io.ObjectOutputStream;  編碼

  7. import java.security.*;  加密

  8. import javax.crypto.Cipher;  

  9. import javax.crypto.KeyGenerator;  

  10. import javax.crypto.SecretKey;  

  11. /**

  12. * 加密解密

  13. *

  14. * @author shy.qiu

  15. * @since  http://blog.csdn.net/qiushyfm

  16. */

  17. publicclass CryptTest {  

  18. /**

  19.     * 進行MD5加密

  20.     *

  21.     * @param info

  22.     *            要加密的信息

  23.     * @return String 加密後的字符串

  24.     */

  25. public String encryptToMD5(String info) {  

  26. byte[] digesta = null;  

  27. try {  

  28. // 獲得一個md5的消息摘要

  29.            MessageDigest alga = MessageDigest.getInstance("MD5");  

  30. // 添加要進行計算摘要的信息

  31.            alga.update(info.getBytes());  

  32. // 獲得該摘要

  33.            digesta = alga.digest();  

  34.        } catch (NoSuchAlgorithmException e) {  

  35.            e.printStackTrace();  

  36.        }  

  37. // 將摘要轉爲字符串

  38.        String rs = byte2hex(digesta);  

  39. return rs;  

  40.    }  

  41. /**

  42.     * 進行SHA加密

  43.     *

  44.     * @param info

  45.     *            要加密的信息

  46.     * @return String 加密後的字符串

  47.     */

  48. public String encryptToSHA(String info) {  

  49. byte[] digesta = null;  

  50. try {  

  51. // 獲得一個SHA-1的消息摘要

  52.            MessageDigest alga = MessageDigest.getInstance("SHA-1");  

  53. // 添加要進行計算摘要的信息

  54.            alga.update(info.getBytes());  

  55. // 獲得該摘要

  56.            digesta = alga.digest();  

  57.        } catch (NoSuchAlgorithmException e) {  

  58.            e.printStackTrace();  

  59.        }  

  60. // 將摘要轉爲字符串

  61.        String rs = byte2hex(digesta);  

  62. return rs;  

  63.    }  

  64. // //////////////////////////////////////////////////////////////////////////

  65. /**

  66.     * 建立密匙

  67.     *

  68.     * @param algorithm

  69.     *            加密算法,可用 DES,DESede,Blowfish

  70.     * @return SecretKey 祕密(對稱)密鑰

  71.     */

  72. public SecretKey createSecretKey(String algorithm) {  

  73. // 聲明KeyGenerator對象

  74.        KeyGenerator keygen;  

  75. // 聲明 密鑰對象

  76.        SecretKey deskey = null;  

  77. try {  

  78. // 返回生成指定算法的祕密密鑰的 KeyGenerator 對象

  79.            keygen = KeyGenerator.getInstance(algorithm);  

  80. // 生成一個密鑰

  81.            deskey = keygen.generateKey();  

  82.        } catch (NoSuchAlgorithmException e) {  

  83.            e.printStackTrace();  

  84.        }  

  85. // 返回密匙

  86. return deskey;  

  87.    }  

  88. /**

  89.     * 根據密匙進行DES加密

  90.     *

  91.     * @param key

  92.     *            密匙

  93.     * @param info

  94.     *            要加密的信息

  95.     * @return String 加密後的信息

  96.     */

  97. public String encryptToDES(SecretKey key, String info) {  

  98. // 定義 加密算法,可用 DES,DESede,Blowfish

  99.        String Algorithm = "DES";  

  100. // 加密隨機數生成器 (RNG),(能夠不寫)

  101.        SecureRandom sr = new SecureRandom();  

  102. // 定義要生成的密文

  103. byte[] cipherByte = null;  

  104. try {  

  105. // 獲得加密/解密器

  106.            Cipher c1 = Cipher.getInstance(Algorithm);  

  107. // 用指定的密鑰和模式初始化Cipher對象

  108. // 參數:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

  109.            c1.init(Cipher.ENCRYPT_MODE, key, sr);  

  110. // 對要加密的內容進行編碼處理,

  111.            cipherByte = c1.doFinal(info.getBytes());  

  112.        } catch (Exception e) {  

  113.            e.printStackTrace();  

  114.        }  

  115. // 返回密文的十六進制形式

  116. return byte2hex(cipherByte);  

  117.    }  

  118. /**

  119.     * 根據密匙進行DES解密

  120.     *

  121.     * @param key

  122.     *            密匙

  123.     * @param sInfo

  124.     *            要解密的密文

  125.     * @return String 返回解密後信息

  126.     */

  127. public String decryptByDES(SecretKey key, String sInfo) {  

  128. // 定義 加密算法,

  129.        String Algorithm = "DES";  

  130. // 加密隨機數生成器 (RNG)

  131.        SecureRandom sr = new SecureRandom();  

  132. byte[] cipherByte = null;  

  133. try {  

  134. // 獲得加密/解密器

  135.            Cipher c1 = Cipher.getInstance(Algorithm);  

  136. // 用指定的密鑰和模式初始化Cipher對象

  137.            c1.init(Cipher.DECRYPT_MODE, key, sr);  

  138. // 對要解密的內容進行編碼處理

  139.            cipherByte = c1.doFinal(hex2byte(sInfo));  

  140.        } catch (Exception e) {  

  141.            e.printStackTrace();  

  142.        }  

  143. // return byte2hex(cipherByte);

  144. returnnew String(cipherByte);  

  145.    }  

  146. // /////////////////////////////////////////////////////////////////////////////

  147. /**

  148.     * 建立密匙組,並將公匙,私匙放入到指定文件中

  149.     *

  150.     * 默認放入mykeys.bat文件中

  151.     */

  152. publicvoid createPairKey() {  

  153. try {  

  154. // 根據特定的算法一個密鑰對生成器

  155.            KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");  

  156. // 加密隨機數生成器 (RNG)

  157.            SecureRandom random = new SecureRandom();  

  158. // 從新設置此隨機對象的種子

  159.            random.setSeed(1000);  

  160. // 使用給定的隨機源(和默認的參數集合)初始化肯定密鑰大小的密鑰對生成器

  161.            keygen.initialize(512, random);// keygen.initialize(512);

  162. // 生成密鑰組

  163.            KeyPair keys = keygen.generateKeyPair();  

  164. // 獲得公匙

  165.            PublicKey pubkey = keys.getPublic();  

  166. // 獲得私匙

  167.            PrivateKey prikey = keys.getPrivate();  

  168. // 將公匙私匙寫入到文件當中

  169.            doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });  

  170.        } catch (NoSuchAlgorithmException e) {  

  171.            e.printStackTrace();  

  172.        }  

  173.    }  

  174. /**

  175.     * 利用私匙對信息進行簽名 把簽名後的信息放入到指定的文件中

  176.     *

  177.     * @param info

  178.     *            要簽名的信息

  179.     * @param signfile

  180.     *            存入的文件

  181.     */

  182. publicvoid signToInfo(String info, String signfile) {  

  183. // 從文件當中讀取私匙

  184.        PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);  

  185. // 從文件中讀取公匙

  186.        PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);  

  187. try {  

  188. // Signature 對象可用來生成和驗證數字簽名

  189.            Signature signet = Signature.getInstance("DSA");  

  190. // 初始化簽署簽名的私鑰

  191.            signet.initSign(myprikey);  

  192. // 更新要由字節簽名或驗證的數據

  193.            signet.update(info.getBytes());  

  194. // 簽署或驗證全部更新字節的簽名,返回簽名

  195. byte[] signed = signet.sign();  

  196. // 將數字簽名,公匙,信息放入文件中

  197.            doObjToFile(signfile, new Object[] { signed, mypubkey, info });  

  198.        } catch (Exception e) {  

  199.            e.printStackTrace();  

  200.        }  

  201.    }  

  202. /**

  203.     * 讀取數字簽名文件 根據公匙,簽名,信息驗證信息的合法性

  204.     *

  205.     * @return true 驗證成功 false 驗證失敗

  206.     */

  207. publicboolean validateSign(String signfile) {  

  208. // 讀取公匙

  209.        PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);  

  210. // 讀取簽名

  211. byte[] signed = (byte[]) getObjFromFile(signfile, 1);  

  212. // 讀取信息

  213.        String info = (String) getObjFromFile(signfile, 3);  

  214. try {  

  215. // 初始一個Signature對象,並用公鑰和簽名進行驗證

  216.            Signature signetcheck = Signature.getInstance("DSA");  

  217. // 初始化驗證簽名的公鑰

  218.            signetcheck.initVerify(mypubkey);  

  219. // 使用指定的 byte 數組更新要簽名或驗證的數據

  220.            signetcheck.update(info.getBytes());  

  221.            System.out.println(info);  

  222. // 驗證傳入的簽名

  223. return signetcheck.verify(signed);  

  224.        } catch (Exception e) {  

  225.            e.printStackTrace();  

  226. returnfalse;  

  227.        }  

  228.    }  

  229. /**

  230.     * 將二進制轉化爲16進制字符串

  231.     *

  232.     * @param b

  233.     *            二進制字節數組

  234.     * @return String

  235.     */

  236. public String byte2hex(byte[] b) {  

  237.        String hs = "";  

  238.        String stmp = "";  

  239. for (int n = 0; n < b.length; n++) {  

  240.            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));  

  241. if (stmp.length() == 1) {  

  242.                hs = hs + "0" + stmp;  

  243.            } else {  

  244.                hs = hs + stmp;  

  245.            }  

  246.        }  

  247. return hs.toUpperCase();  

  248.    }  

  249. /**

  250.     * 十六進制字符串轉化爲2進制

  251.     *

  252.     * @param hex

  253.     * @return

  254.     */

  255. publicbyte[] hex2byte(String hex) {  

  256. byte[] ret = newbyte[8];  

  257. byte[] tmp = hex.getBytes();  

  258. for (int i = 0; i < 8; i++) {  

  259.            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);  

  260.        }  

  261. return ret;  

  262.    }  

  263. /**

  264.     * 將兩個ASCII字符合成一個字節; 如:"EF"--> 0xEF

  265.     *

  266.     * @param src0

  267.     *            byte

  268.     * @param src1

  269.     *            byte

  270.     * @return byte

  271.     */

  272. publicstaticbyte uniteBytes(byte src0, byte src1) {  

  273. byte _b0 = Byte.decode("0x" + new String(newbyte[] { src0 }))  

  274.                .byteValue();  

  275.        _b0 = (byte) (_b0 << 4);  

  276. byte _b1 = Byte.decode("0x" + new String(newbyte[] { src1 }))  

  277.                .byteValue();  

  278. byte ret = (byte) (_b0 ^ _b1);  

  279. return ret;  

  280.    }  

  281. /**

  282.     * 將指定的對象寫入指定的文件

  283.     *

  284.     * @param file

  285.     *            指定寫入的文件

  286.     * @param objs

  287.     *            要寫入的對象

  288.     */

  289. publicvoid doObjToFile(String file, Object[] objs) {  

  290.        ObjectOutputStream oos = null;  

  291. try {  

  292.            FileOutputStream fos = new FileOutputStream(file);  

  293.            oos = new ObjectOutputStream(fos);  

  294. for (int i = 0; i < objs.length; i++) {  

  295.                oos.writeObject(objs[i]);  

  296.            }  

  297.        } catch (Exception e) {  

  298.            e.printStackTrace();  

  299.        } finally {  

  300. try {  

  301.                oos.close();  

  302.            } catch (IOException e) {  

  303.                e.printStackTrace();  

  304.            }  

  305.        }  

  306.    }  

  307. /**

  308.     * 返回在文件中指定位置的對象

  309.     *

  310.     * @param file

  311.     *            指定的文件

  312.     * @param i

  313.     *            從1開始

  314.     * @return

  315.     */

  316. public Object getObjFromFile(String file, int i) {  

  317.        ObjectInputStream ois = null;  

  318.        Object obj = null;  

  319. try {  

  320.            FileInputStream fis = new FileInputStream(file);  

  321.            ois = new ObjectInputStream(fis);  

  322. for (int j = 0; j < i; j++) {  

  323.                obj = ois.readObject();  

  324.            }  

  325.        } catch (Exception e) {  

  326.            e.printStackTrace();  

  327.        } finally {  

  328. try {  

  329.                ois.close();  

  330.            } catch (IOException e) {  

  331.                e.printStackTrace();  

  332.            }  

  333.        }  

  334. return obj;  

  335.    }  

  336. /**

  337.     * 測試

  338.     *

  339.     * @param args

  340.     */

  341. publicstaticvoid main(String[] args) {  

  342.        CryptTest jiami = new CryptTest();  

  343. // 執行MD5加密"Hello world!"

  344.        System.out.println("Hello通過MD5:" + jiami.encryptToMD5("Hello"));  

  345. // 生成一個DES算法的密匙

  346.        SecretKey key = jiami.createSecretKey("DES");  

  347. // 用密匙加密信息"Hello world!"

  348.        String str1 = jiami.encryptToDES(key, "Hello");  

  349.        System.out.println("使用des加密信息Hello爲:" + str1);  

  350. // 使用這個密匙解密

  351.        String str2 = jiami.decryptByDES(key, str1);  

  352.        System.out.println("解密後爲:" + str2);  

  353. // 建立公匙和私匙

  354.        jiami.createPairKey();  

  355. // 對Hello world!使用私匙進行簽名

  356.        jiami.signToInfo("Hello", "mysign.bat");  

  357. // 利用公匙對簽名進行驗證。

  358. if (jiami.validateSign("mysign.bat")) {  

  359.            System.out.println("Success!");  

  360.        } else {  

  361.            System.out.println("Fail!");  

  362.        }  

  363.    }  

  364. }  


用到的重要的類
javax.crypto.KeyGenerator
public final SecretKey generateKey()生成一個密鑰
public static final KeyGenerator getInstance(String algorithm) 返回生成指定算法的祕密密鑰的KeyGenerator對象。
javax.crypto 接口 SecretKey
javax.crypto.Cipher 此類爲加密和解密提供密碼功能。它構成了 Java Cryptographic Extension (JCE) 框架的核心
public final void init(int opmode,Key key)
public final byte[] doFinal(byte[] input) 按單部分操做加密或解密數據,或者結束一個多部分操做
java.security.KeyPairGenerator
static KeyPairGenerator getInstance(String algorithm)
回生成指定算法的 public/private 密鑰對的 KeyPairGenerator 對象。
java.security.Signature
使用 Signature 對象簽名數據或驗證簽名包括如下三個階段:
1:初始化,使用
初始化驗證簽名的公鑰(請參見 initVerify),或使用
初始化簽署簽名的私鑰(也能夠選擇「安全隨機數生成器」)initSign(PrivateKey)和initSign(PrivateKey, SecureRandom))。
2:更新
根據初始化類型,這可更新要簽名或驗證的字節。請參見 update 方法。
3:簽署或驗證全部更新字節的簽名。請參見 sign 方法和 verify 方法。

相關文章
相關標籤/搜索