`
冷静
  • 浏览: 146903 次
  • 性别: Icon_minigender_1
  • 来自: 佛山
社区版块
存档分类
最新评论

Java加密技术(四)

    博客分类:
  • Java
 
阅读更多

文章转自:http://snowolf.iteye.com/blog/381767 

RSA
    这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。
    这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。

流程分析:

  1. 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
  2. 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
  3. 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。



按如上步骤给出序列图,如下:



  • 通过java代码实现如下:Coder类见 Java加密技术(一)
  • Java代码 复制代码 收藏代码
    import java.security.Key;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    
    /**
     * RSA安全编码组件
     * 
     * @author 梁栋
     * @version 1.0
     * @since 1.0
     */
    public abstract class RSACoder extends Coder {
    	public static final String KEY_ALGORITHM = "RSA";
    	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    
    	private static final String PUBLIC_KEY = "RSAPublicKey";
    	private static final String PRIVATE_KEY = "RSAPrivateKey";
    
    	/**
    	 * 用私钥对信息生成数字签名
    	 * 
    	 * @param data
    	 *            加密数据
    	 * @param privateKey
    	 *            私钥
    	 * 
    	 * @return
    	 * @throws Exception
    	 */
    	public static String sign(byte[] data, String privateKey) throws Exception {
    		// 解密由base64编码的私钥
    		byte[] keyBytes = decryptBASE64(privateKey);
    
    		// 构造PKCS8EncodedKeySpec对象
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    
    		// KEY_ALGORITHM 指定的加密算法
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    
    		// 取私钥匙对象
    		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    
    		// 用私钥对信息生成数字签名
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initSign(priKey);
    		signature.update(data);
    
    		return encryptBASE64(signature.sign());
    	}
    
    	/**
    	 * 校验数字签名
    	 * 
    	 * @param data
    	 *            加密数据
    	 * @param publicKey
    	 *            公钥
    	 * @param sign
    	 *            数字签名
    	 * 
    	 * @return 校验成功返回true 失败返回false
    	 * @throws Exception
    	 * 
    	 */
    	public static boolean verify(byte[] data, String publicKey, String sign)
    			throws Exception {
    
    		// 解密由base64编码的公钥
    		byte[] keyBytes = decryptBASE64(publicKey);
    
    		// 构造X509EncodedKeySpec对象
    		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    
    		// KEY_ALGORITHM 指定的加密算法
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    
    		// 取公钥匙对象
    		PublicKey pubKey = keyFactory.generatePublic(keySpec);
    
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initVerify(pubKey);
    		signature.update(data);
    
    		// 验证签名是否正常
    		return signature.verify(decryptBASE64(sign));
    	}
    
    	/**
    	 * 解密<br>
    	 * 用私钥解密
    	 * 
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryptByPrivateKey(byte[] data, String key)
    			throws Exception {
    		// 对密钥解密
    		byte[] keyBytes = decryptBASE64(key);
    
    		// 取得私钥
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    
    		// 对数据解密
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.DECRYPT_MODE, privateKey);
    
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 解密<br>
    	 * 用私钥解密
    	 * 
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryptByPublicKey(byte[] data, String key)
    			throws Exception {
    		// 对密钥解密
    		byte[] keyBytes = decryptBASE64(key);
    
    		// 取得公钥
    		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key publicKey = keyFactory.generatePublic(x509KeySpec);
    
    		// 对数据解密
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.DECRYPT_MODE, publicKey);
    
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 加密<br>
    	 * 用公钥加密
    	 * 
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptByPublicKey(byte[] data, String key)
    			throws Exception {
    		// 对公钥解密
    		byte[] keyBytes = decryptBASE64(key);
    
    		// 取得公钥
    		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key publicKey = keyFactory.generatePublic(x509KeySpec);
    
    		// 对数据加密
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 加密<br>
    	 * 用私钥加密
    	 * 
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptByPrivateKey(byte[] data, String key)
    			throws Exception {
    		// 对密钥解密
    		byte[] keyBytes = decryptBASE64(key);
    
    		// 取得私钥
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    
    		// 对数据加密
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 取得私钥
    	 * 
    	 * @param keyMap
    	 * @return
    	 * @throws Exception
    	 */
    	public static String getPrivateKey(Map<String, Object> keyMap)
    			throws Exception {
    		Key key = (Key) keyMap.get(PRIVATE_KEY);
    
    		return encryptBASE64(key.getEncoded());
    	}
    
    	/**
    	 * 取得公钥
    	 * 
    	 * @param keyMap
    	 * @return
    	 * @throws Exception
    	 */
    	public static String getPublicKey(Map<String, Object> keyMap)
    			throws Exception {
    		Key key = (Key) keyMap.get(PUBLIC_KEY);
    
    		return encryptBASE64(key.getEncoded());
    	}
    
    	/**
    	 * 初始化密钥
    	 * 
    	 * @return
    	 * @throws Exception
    	 */
    	public static Map<String, Object> initKey() throws Exception {
    		KeyPairGenerator keyPairGen = KeyPairGenerator
    				.getInstance(KEY_ALGORITHM);
    		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(PUBLIC_KEY, publicKey);
    		keyMap.put(PRIVATE_KEY, privateKey);
    		return keyMap;
    	}
    }
    


    再给出一个测试类:

    Java代码 复制代码 收藏代码
    import static org.junit.Assert.*;
    
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.Map;
    
    /**
     * 
     * @author 梁栋
     * @version 1.0
     * @since 1.0
     */
    public class RSACoderTest {
    	private String publicKey;
    	private String privateKey;
    
    	@Before
    	public void setUp() throws Exception {
    		Map<String, Object> keyMap = RSACoder.initKey();
    
    		publicKey = RSACoder.getPublicKey(keyMap);
    		privateKey = RSACoder.getPrivateKey(keyMap);
    		System.err.println("公钥: \n\r" + publicKey);
    		System.err.println("私钥: \n\r" + privateKey);
    	}
    
    	@Test
    	public void test() throws Exception {
    		System.err.println("公钥加密——私钥解密");
    		String inputStr = "abc";
    		byte[] data = inputStr.getBytes();
    
    		byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);
    
    		byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
    				privateKey);
    
    		String outputStr = new String(decodedData);
    		System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    		assertEquals(inputStr, outputStr);
    
    	}
    
    	@Test
    	public void testSign() throws Exception {
    		System.err.println("私钥加密——公钥解密");
    		String inputStr = "sign";
    		byte[] data = inputStr.getBytes();
    
    		byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
    
    		byte[] decodedData = RSACoder
    				.decryptByPublicKey(encodedData, publicKey);
    
    		String outputStr = new String(decodedData);
    		System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    		assertEquals(inputStr, outputStr);
    
    		System.err.println("私钥签名——公钥验证签名");
    		// 产生签名
    		String sign = RSACoder.sign(encodedData, privateKey);
    		System.err.println("签名:\r" + sign);
    
    		// 验证签名
    		boolean status = RSACoder.verify(encodedData, publicKey, sign);
    		System.err.println("状态:\r" + status);
    		assertTrue(status);
    
    	}
    
    }
    


    控制台输出:

    Console代码 复制代码 收藏代码
    公钥: 
    
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
    EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
    1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB
    
    私钥: 
    
    MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmY
    FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
    GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
    gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
    /MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
    uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
    rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
    QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
    Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
    o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA
    fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
    nfpFpBJ2dw==
    
    公钥加密——私钥解密
    加密前: abc
    
    解密后: abc
    公钥: 
    
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
    9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
    l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB
    
    私钥: 
    
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
    g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
    PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
    gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
    mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY
    j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
    gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
    9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
    9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
    mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
    QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
    I2k1Afmrwyw=
    
    私钥加密——公钥解密
    加密前: sign
    
    解密后: sign
    私钥签名——公钥验证签名
    签名:
    ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
    mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
    i3wwbYWs9wSzIf0UjlM=
    
    状态:
    true
    
    



        简要总结一下,使用公钥加密、私钥解密,完成了乙方到甲方的一次数据传递,通过私钥加密、公钥解密,同时通过私钥签名、公钥验证签名,完成了一次甲方到乙方的数据传递与验证,两次数据传递完成一整套的数据交互!

    类似数字签名,数字信封是这样描述的:

    数字信封
      数字信封用加密技术来保证只有特定的收信人才能阅读信的内容。
    流程:
        信息发送方采用对称密钥来加密信息,然后再用接收方的公钥来加密此对称密钥(这部分称为数字信封),再将它和信息一起发送给接收方;接收方先用相应的私钥打开数字信封,得到对称密钥,然后使用对称密钥再解开信息。


    相关链接:
    Java加密技术(一)
    Java加密技术(二)
    Java加密技术(三)
    Java加密技术(四)
    Java加密技术(五)
    Java加密技术(六)
    Java加密技术(七)
    Java加密技术(八)
    Java加密技术(九)
    Java加密技术(十)

    分享到:
    评论

    相关推荐

      Java 加密技术汇总

      ### Java 加密技术汇总 #### 一、概述 在当今高度数字化的世界中,信息安全变得尤为重要。Java作为一种广泛应用的编程语言,在处理数据加密方面提供了多种工具和技术。本文将深入探讨Java中常用的加密技术,包括...

      java加密技术详解

      ### Java加密技术详解:以MD5为例 在Java中,加密技术是确保数据安全和完整性的关键工具之一。本文将深入探讨Java中的加密技术,特别是MD5加密算法,通过实例和代码片段,帮助读者理解其工作原理及如何在实际项目中...

      Java加密技术

      Java加密技术

      Java加密技术(四)

      总结来说,Java加密技术第四部分主要介绍了ECC加密技术的概念、其在Java中的有限支持,以及如何通过Java代码实现ECC的加密和解密操作。尽管Java的标准实现并不直接支持ECC的加密/解密,但可以通过扩展和利用非公开...

      基于JAVA的加密算法(包括10种加密技术)

      Java加密技术(一) 关键字: java 加密基础, base64, md5, mac, sha, 单向加密 。。。。。。。。。。。。。。

      java加密技术大全

      Java加密技术是保护数据安全的重要工具,广泛应用于网络通信、数据存储、数字签名等领域。本资源包涵盖了Java中常见的加密算法和技术,包括基础的哈希算法、对称加密、非对称加密以及证书签名和SSL/TLS协议。下面将...

      java加密技术 (网页版)

      Java加密技术是软件开发中一个重要的安全领域,主要用于保护数据的隐私性和完整性。在这个网页版的资源中,可能涵盖了各种加密算法的Java实现,以及它们之间的比较。让我们深入探讨一下这些知识点。 首先,我们来看...

      运用加密技术保护java源代码

      因此,运用加密技术保护Java源代码成为了一项重要的课题。 ### Java源代码加密的重要性 Java源代码加密主要涉及两个层面:一是源代码本身的安全,二是编译后的字节码(.class文件)的安全。对于源代码,加密可以...

      JAVA加密技术.docx

      在Java编程中,加密技术是确保信息安全的关键组成部分。本文将探讨几种常见的加密算法,包括单向加密和对称及非对称加密算法。首先,我们来看基础的单向加密算法,如BASE64、MD5、SHA和HMAC。 **BASE64** 是一种...

      java加密技术研究

      java加密技术研究

      Java加密技术(一)

      总之,Java加密技术提供了丰富的工具和算法,可以帮助开发者构建安全的应用程序。然而,随着技术的发展,加密算法的安全性也需要不断更新,以抵御新的攻击手段。在设计系统时,应考虑最新的安全标准和最佳实践,确保...

      java加密技术

      Java加密技术是Java编程语言中用于保障数据安全的一系列加密方法和技术,它包括了单向加密算法、对称加密算法、非对称加密算法以及加密算法的高级应用如数字签名和数字证书等。本文将详细介绍这些加密技术,并结合...

      Java加密技术全集

      Java加密技术是信息安全领域的重要组成部分,它用于保护数据的隐私性和完整性。在这个“Java加密技术全集”中,我们将会探讨MD5、SHA和BASE64等常见的加密算法及其在Java中的实现。 MD5(Message-Digest Algorithm ...

      Java加密技术(三)

      Java加密技术(三),相当有用的加密技术(三),值得学习参考!希望对你有点帮助!

      Java加密技术 pdf版

      Java加密技术 pdf版 加密解密,曾经是我一个毕业设计的重要组件。在工作了多年以后回想当时那个加密、解密算法,实在是太单纯了。 言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书

      Java加密技术(技巧与实例) pdf.rar

      Java加密技术是软件开发中一个至关重要的领域,特别是在保护数据安全、验证信息完整性和实现安全通信方面。本书“Java加密技术(技巧与实例)”深入浅出地探讨了这一主题,为开发者提供了丰富的实践指导。以下是一些...

      Java加密技术MD5/BASE64等加密技术

      Java加密技术是软件开发中的重要组成部分,特别是在保护数据安全、用户隐私以及确保网络通信的完整性方面。本资源主要关注两种常见的加密算法:MD5(Message-Digest Algorithm 5)和BASE64编码,它们在Java中有着...

    Global site tag (gtag.js) - Google Analytics