DES和RSA算法的java实现
2019獨角獸企業重金招聘Python工程師標準>>>
一、對稱加密算法
? ? ? 對稱加密算法是應用較早的加密算法,技術成熟。在對稱加密算法中,數據發信方將明文(原始數據)和加密密鑰一起經過特殊加密算法處理后,使其變成復雜的加密密文發送出去。收信方收到密文后,若想解讀原文,則需要使用加密用過的密鑰及相同算法的逆算法對密文進行解密,才能使其恢復成可讀明文。在對稱加密算法中,使用的密鑰只有一個,發收信雙方都使用這個密鑰對數據進行加密和解密,這就要求解密方事先必須知道加密密鑰。
? ? ? 對稱加密算法的優點是:算法公開、計算量小、加密速度快、加密效率高。缺點是:首先,交易雙方都使用同樣鑰匙,安全性得不到保證。其次,每對用戶每次使用對稱加密算法時,都需要使用其他人不知道的惟一鑰匙,這會使得發收信雙方所擁有的鑰匙數量呈幾何級數增長,密鑰管理成為用戶的負擔。對稱加密算法在分布式網絡系統上使用較為困難,主要是因為密鑰管理困難,使用成本較高。
1.DES算法
? ? ? DES算法是最流行的對稱加密算法,全稱是Data?Encryption?Standard,即數據加密算法,它是IBM公司于1975年研究成功并公開發表的。DES算法的入口參數有三個:Key、Data、Mode。其中Key為8個字節共64位,是DES算法的工作密鑰;Data也為8個字節64位,是要被加密或被解密的數據;Mode為DES的工作方式,有兩種:加密或解密。
? ? ? 可以對數據進行三次DES算法,從而形成3DES算法。此算法相當于是對每個數據塊應用三次DES加密算法。由于計算機運算能力的增強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設計用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼算法。對此算法的介紹,本文后面不再贅述。
a.算法原理
? ? ? DES算法把64位的明文輸入塊變為64位的密文輸出塊,它所使用的密鑰也是64位,其算法主要分為兩步:
1.初始置換
? ? ? 其功能是把輸入的64位數據塊按位重新組合,并把輸出分為L0、R0兩部分,每部分各長32位,其置換規則為將輸入的第58位換到第一位,第50位換到第2位……依此類推,最后一位是原來的第7位。L0、R0則是換位輸出后的兩部分,L0是輸出的左32位,R0是右32位,例:設置換前的輸入值為D1D2D3……D64,則經過初始置換后的結果為:L0=D58D50……D8;R0=D57D49……D7。
2.逆置換
? ? ? 經過16次迭代運算后,得到L16、R16,將此作為輸入,進行逆置換,逆置換正好是初始置換的逆運算,由此即得到密文輸出。
b.DES算法在Java中的實現及運用
? ? ? Java中為安全框架提供類和接口。JDK?安全?API?是?Java?編程語言的核心?API,位于?java.security?包(及其子包),以及sun.securityAPI包(及其子包)中。設計用于幫助開發人員在程序中同時使用低級和高級安全功能。
應用實例:
????
?? ?private static int parse(char c) {
?? ??? ?if (c >= 'a')
?? ??? ??? ?return (c - 'a' + 10) & 0x0f;
?? ??? ?if (c >= 'A')
?? ??? ??? ?return (c - 'A' + 10) & 0x0f;
?? ??? ?return (c - '0') & 0x0f;
?? ?}
?? ?// 從十六進制字符串到字節數組轉換
?? ?public static byte[] HexString2Bytes(String hexstr) {
?? ??? ?byte[] b = new byte[hexstr.length() / 2];
?? ??? ?int j = 0;
?? ??? ?for (int i = 0; i < b.length; i++) {
?? ??? ??? ?char c0 = hexstr.charAt(j++);
?? ??? ??? ?char c1 = hexstr.charAt(j++);
?? ??? ??? ?b[i] = (byte) ((parse(c0) << 4) | parse(c1));
?? ??? ?}
?? ??? ?return b;
?? ?}
?? ?private static SecretKey keyGenerator(String keyStr) throws Exception {
?? ??? ?byte input[] = HexString2Bytes(keyStr);
?? ??? ?DESKeySpec desKey = new DESKeySpec(input);
?? ??? ?// 創建一個密匙工廠,然后用它把DESKeySpec轉換成
?? ??? ?SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
?? ??? ?SecretKey securekey = keyFactory.generateSecret(desKey);
?? ??? ?return securekey;
?? ?}
?? ?// 加密
?? ?public static String encrypt(String data, String key) throws Exception {
?? ??? ?Key deskey = keyGenerator(key);
?? ??? ?// 實例化Cipher對象,它用于完成實際的加密操作
?? ??? ?Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
?? ??? ?SecureRandom random = new SecureRandom();
?? ??? ?// 初始化Cipher對象,設置為加密模式
?? ??? ?cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
?? ??? ?byte[] results = cipher.doFinal(data.getBytes());
?? ??? ?// 執行加密操作。加密后的結果通常都會用Base64編碼進行傳輸
?? ??? ?return Base64.encodeBase64String(results);
?? ?}
?? ?// 解密
?? ?public static String decrypt(String data, String key) throws Exception {
?? ??? ?Key deskey = keyGenerator(key);
?? ??? ?Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
?? ??? ?// 初始化Cipher對象,設置為解密模式
?? ??? ?cipher.init(Cipher.DECRYPT_MODE, deskey);
?? ??? ?// 執行解密操作
?? ??? ?return new String(cipher.doFinal(Base64.decodeBase64(data)));
?? ?}
?
二、非對稱加密算法
? ? ? 非對稱加密算法的核心源于數學問題,它存在公鑰和私鑰的概念,要完成加解密操作,需要兩個密鑰同時參與。
? ? ? 非對稱密碼體制的特點:算法強度復雜、安全性依賴于算法與密鑰但是由于其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。對稱密碼體制中只有一種密鑰,并且是非公開的,如果要解密就得讓對方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就可以不需要像對稱密碼那樣傳輸對方的密鑰了。這樣安全性就大了很多。
1.RSA算法
? ? ? RSA加密算法是一種典型的非對稱加密算法,它基于大數的因式分解數學難題,它也是應用最廣泛的非對稱加密算法,于1978年由美國麻省理工學院(MIT)的三位學著:Ron?Rivest、Adi?Shamir?和?Leonard?Adleman?共同提出。
a.算法原理
? ? ? RSA的原理較為簡單。我們假設有消息發送方A和消息接收方B,通過下面的幾個步驟,我們就可以完成消息的加密傳遞:
? ? ? ? ?1)消息發送方A在本地構建密鑰對,公鑰和私鑰;
? ? ? ? ?2)消息發送方A將產生的公鑰發送給消息接收方B;
? ? ? ? ?3)B向A發送數據時,通過公鑰進行加密,A接收到數據后通過私鑰進行解密,完成一次通信;
? ? ? ? ?4)反之,A向B發送數據時,通過私鑰對數據進行加密,B接收到數據后通過公鑰進行解密。
? ? ? 由于公鑰是消息發送方A暴露給消息接收方B的,所以這種方式也存在一定的安全隱患,如果公鑰在數據傳輸過程中泄漏,則A通過私鑰加密的數據就可能被解密。
? ? ? 如果要建立更安全的加密消息傳遞模型,需要消息發送方和消息接收方各構建一套密鑰對,并分別將各自的公鑰暴露給對方,在進行消息傳遞時,A通過B的公鑰對數據加密,B接收到消息通過B的私鑰進行解密,反之,B通過A的公鑰進行加密,A接收到消息后通過A的私鑰進行解密。
? ? ? 當然,這種方式可能存在數據傳遞被模擬的隱患,我們可以通過數字簽名等技術進行安全性的進一步提升。由于存在多次的非對稱加解密,這種方式帶來的效率問題也更加嚴重。
DES算法在Java中的實現及運用:???
?// 用私鑰對信息生成數字簽名
?? ?public static String sign(byte[] data, String privateKey) throws Exception {
?? ??? ?// 解密由base64編碼的私鑰
?? ??? ?byte[] keyBytes = decryptBASE64(privateKey);
?? ??? ?// 構造PKCS8EncodedKeySpec對象
?? ??? ?PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?// 取私鑰匙對象
?? ??? ?PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
?? ??? ?// 用私鑰對信息生成數字簽名
?? ??? ?Signature signature = Signature.getInstance("MD5withRSA");
?? ??? ?signature.initSign(priKey);
?? ??? ?signature.update(data);
?? ??? ?return encryptBASE64(signature.sign());
?? ?}
?? ?// 校驗數字簽名
?? ?public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
?? ??? ?// 解密由base64編碼的公鑰
?? ??? ?byte[] keyBytes = decryptBASE64(publicKey);
?? ??? ?// 構造X509EncodedKeySpec對象
?? ??? ?X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?// 取公鑰匙對象
?? ??? ?PublicKey pubKey = keyFactory.generatePublic(keySpec);
?? ??? ?Signature signature = Signature.getInstance("MD5withRSA");
?? ??? ?signature.initVerify(pubKey);
?? ??? ?signature.update(data);
?? ??? ?// 驗證簽名是否正常
?? ??? ?return signature.verify(decryptBASE64(sign));
?? ?}
?? ?// 對私鑰解密
?? ?public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
?? ??? ?// 對密鑰解密
?? ??? ?byte[] keyBytes = decryptBASE64(key);
?? ??? ?// 取得私鑰
?? ??? ?PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
?? ??? ?// 對數據解密
?? ??? ?Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
?? ??? ?cipher.init(Cipher.DECRYPT_MODE, privateKey);
?? ??? ?return cipher.doFinal(data);
?? ?}
?? ?// 用公鑰解密
?? ?public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
?? ??? ?// 對密鑰解密
?? ??? ?byte[] keyBytes = decryptBASE64(key);
?? ??? ?// 取得公鑰
?? ??? ?X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?Key publicKey = keyFactory.generatePublic(x509KeySpec);
?? ??? ?// 對數據解密
?? ??? ?Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
?? ??? ?cipher.init(Cipher.DECRYPT_MODE, publicKey);
?? ??? ?return cipher.doFinal(data);
?? ?}
?? ?// 用公鑰加密
?? ?public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
?? ??? ?// 對公鑰解密
?? ??? ?byte[] keyBytes = decryptBASE64(key);
?? ??? ?// 取得公鑰
?? ??? ?X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?Key publicKey = keyFactory.generatePublic(x509KeySpec);
?? ??? ?// 對數據加密
?? ??? ?Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
?? ??? ?cipher.init(Cipher.ENCRYPT_MODE, publicKey);
?? ??? ?return cipher.doFinal(data);
?? ?}
?? ?// 用私鑰加密
?? ?public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
?? ??? ?// 對密鑰解密
?? ??? ?byte[] keyBytes = decryptBASE64(key);
?? ??? ?// 取得私鑰
?? ??? ?PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
?? ??? ?KeyFactory keyFactory = KeyFactory.getInstance("RSA");
?? ??? ?Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
?? ??? ?// 對數據加密
?? ??? ?Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
?? ??? ?cipher.init(Cipher.ENCRYPT_MODE, privateKey);
?? ??? ?return cipher.doFinal(data);
?? ?}
?? ?// 取得私鑰
?? ?public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
?? ??? ?Key key = (Key) keyMap.get("RSAPrivateKey");
?? ??? ?return encryptBASE64(key.getEncoded());
?? ?}
?? ?// 取得公鑰
?? ?public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
?? ??? ?Key key = (Key) keyMap.get("RSAPublicKey");
?? ??? ?return encryptBASE64(key.getEncoded());
?? ?}
?? ?// 初始化密鑰
?? ?public static Map<String, Object> initKey() throws Exception {
?? ??? ?KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
?? ??? ?keyPairGen.initialize(1024);
?? ??? ?KeyPair keyPair = keyPairGen.generateKeyPair();
?? ??? ?// 公鑰
?? ??? ?RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
?? ??? ?// 私鑰
?? ??? ?RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
?? ??? ?Map<String, Object> keyMap = new HashMap<String, Object>(2);
?? ??? ?keyMap.put("RSAPublicKey", publicKey);
?? ??? ?keyMap.put("RSAPrivateKey", privateKey);
?? ??? ?return keyMap;
?? ?}
?? ?/** ?
?? ? * BASE64解密 ?
?? ? * ??
?? ? * @param key ?
?? ? * @return ?
?? ? * @throws Exception ?
?? ? */ ? ?
?? ?public static byte[] decryptBASE64(String key) throws Exception { ? ?
?? ? ? ?return (new BASE64Decoder()).decodeBuffer(key); ? ?
?? ?} ? ?
?? ? ? ?
?? ?/** ?
?? ? * BASE64加密 ?
?? ? * ??
?? ? * @param key ?
?? ? * @return ?
?? ? * @throws Exception ?
?? ? */ ? ?
?? ?public static String encryptBASE64(byte[] key) throws Exception { ? ?
?? ? ? ?return (new BASE64Encoder()).encodeBuffer(key); ? ?
?? ?} ? ?
?
轉載于:https://my.oschina.net/u/3383536/blog/1624110
總結
以上是生活随笔為你收集整理的DES和RSA算法的java实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫入门(六) Scrapy
- 下一篇: 激活分区