1. package com.ice.webos.util.security;
  2.  
  3. import java.math.BigInteger;
    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;
  4.  
  5. import javax.crypto.Cipher;
  6.  
  7. /**
    * RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。<br>
    * RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。<br>
    * 数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输过程中不被修改。
    * <ul>
    * 流程分析:
    * <li>甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。</li>
    * <li>甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。</li>
    * <li>乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。 </li>
    * <ul>
    *
    * @author Ice_Liu
    *
    */
    public class RSACryptUtil {
    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";
  8.  
  9. /**
    * 用私钥对信息生成数字签名
    *
    * @param data
    * 加密数据
    * @param privateKey
    * 私钥
    *
    * @return
    * @throws Exception
    */
    public static String sign(byte[] data, String privateKey) throws Exception {
    // 解密由base64编码的私钥
    byte[] keyBytes = CryptUtil.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 CryptUtil.encryptBASE64(signature.sign());
    }
  10.  
  11. /**
    * 校验数字签名
    *
    * @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 = CryptUtil.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(CryptUtil.decryptBASE64(sign));
    }
  12.  
  13. /**
    * 解密<br>
    * 用私钥解密
    *
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
    // 对密钥解密
    byte[] keyBytes = CryptUtil.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);
    }
  14.  
  15. /**
    * 解密<br>
    * 用私钥解密
    *
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
    // 对密钥解密
    byte[] keyBytes = CryptUtil.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);
    }
  16.  
  17. /**
    * 加密<br>
    * 用公钥加密
    *
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
    // 对公钥解密
    byte[] keyBytes = CryptUtil.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);
    }
  18.  
  19. /**
    * 加密<br>
    * 用私钥加密
    *
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
    // 对密钥解密
    byte[] keyBytes = CryptUtil.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);
    }
  20.  
  21. /**
    * 取得私钥
    *
    * @param keyMap
    * @return
    * @throws Exception
    */
    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
    Key key = (Key) keyMap.get(PRIVATE_KEY);
    return CryptUtil.encryptBASE64(key.getEncoded());
    }
  22.  
  23. /**
    * 取得公钥
    *
    * @param keyMap
    * @return
    * @throws Exception
    */
    public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
    Key key = (Key) keyMap.get(PUBLIC_KEY);
    return CryptUtil.encryptBASE64(key.getEncoded());
    }
  24.  
  25. /**
    * 初始化密钥
    *
    * @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;
    }
  26.  
  27. /**
    * @param args
    */
    public static void main(String[] args) {
    try {
    PBECryptUtil.main(args);
    System.out.println("****************************************");
    System.out.println("=====RSA加密与解密=====");
    // 初始化公钥,私钥
    Map<String, Object> keyMap = initKey();
    String publicKey = RSACryptUtil.getPublicKey(keyMap);
    String privateKey = RSACryptUtil.getPrivateKey(keyMap);
    System.out.println("公钥: \n\r" + publicKey);
    System.out.println("私钥: \n\r" + privateKey);
    System.out.println("公钥加密——私钥解密");
    String inputStr = "阿伯才的覆盖";
    byte[] data = inputStr.getBytes("UTF-8");
    // 公钥加密
    byte[] encodedData = RSACryptUtil.encryptByPublicKey(data, publicKey);
    System.out.println("公钥加密后:" + new BigInteger(encodedData).toString(32));
    // 私钥解密
    byte[] decodedData = RSACryptUtil.decryptByPrivateKey(encodedData, privateKey);
    String outputStr = new String(decodedData, "UTF-8");
    System.out.println("加密前: " + inputStr);
    System.out.println("解密后: " + outputStr);
  28.  
  29. System.out.println("私钥加密——公钥解密");
    // 私钥加密
    encodedData = RSACryptUtil.encryptByPrivateKey(data, privateKey);
    System.out.println("私钥加密后:" + new BigInteger(encodedData).toString(32));
    // 公钥解密
    decodedData = RSACryptUtil.decryptByPublicKey(encodedData, publicKey);
    outputStr = new String(decodedData, "UTF-8");
    System.out.println("加密前: " + inputStr);
    System.out.println("解密后: " + outputStr);
  30.  
  31. System.out.println("私钥签名——公钥验证签名");
    // 使用私钥产生签名
    String sign = RSACryptUtil.sign(encodedData, privateKey);
    System.out.println("签名:" + sign);
    // 使用公匙验证签名
    boolean status = RSACryptUtil.verify(encodedData, publicKey, sign);
    System.err.println("验证签名结果:" + status);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
  32.  
  33. }
  34.  
  35. }

转自:http://www.cnblogs.com/liubin0509/archive/2012/01/29/2331075.html

RSA 数据加密和数字签名算法的更多相关文章

  1. 第十四章 数字签名算法--RSA

    注意:本节内容主要参考自 <Java加密与解密的艺术(第2版)>第9章“带密钥的消息摘要算法--数字签名算法” <大型分布式网站架构(设计与实践)>第3章“互联网安全架构” 1 ...

  2. Java数字签名算法--RSA

    签名具有的特性: 安全性 抗否认性 数字签名:带有密钥(公钥.私钥)的消息摘要算法(使用私钥进行签名,使用公钥进行验证) 数字签名算法:RSA.DSA.ECDSA 数字签名特性: 验证数据完整性 认证 ...

  3. 数字签名算法rsa

    数字签名算法消息传递模型 由消息发送方构建密钥对,这里由甲方完成. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消 ...

  4. ECDSA数字签名算法

    一.ECDSA概述 椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟.ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准.它在 ...

  5. JAVA加解密 -- 数字签名算法

    数字签名 – 带有密钥的消息摘要算法 作用:验证数据完整性.认证数据来源.抗否认(OSI参考模型) 私钥签名,公钥验证 RSA 包含非对称算法和数字签名算法 实现代码: //1.初始化密钥 KeyPa ...

  6. .NET Core加解密实战系列之——消息摘要与数字签名算法

    目录 简介 功能依赖 消息摘要算法 MD算法 家族发展史 应用场景 代码实现 MD5 示例代码 SHA算法 应用场景 代码实现 SHA1 SHA256 示例代码 MAC算法 HMAC算法的典型应用 H ...

  7. Windows phone应用开发[19]-RSA数据加密

    在这个系列的第十六章节中Windows phone应用开发[16]-数据加密 中曾详细讲解过windows phone 常用的MD5,HMAC_MD5,DES,TripleDES[3DES] 数据加密 ...

  8. RSA/SHA1加密和数字签名算法在开放平台中的应用

    加密算法 加密算法分为两大类:1.对称加密算法:2.非对称加密算法.   密钥个数 加密 解密 对称加密 一个 使用密钥加密 使用同一个密钥解密 非对称加密 两个,公钥和私钥 使用其中一把密钥加密 使 ...

  9. java数字签名算法之RSA

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

随机推荐

  1. 入门activiti-------1简单运行

    1.下载原料 2.放置位置 3.运行 4.成功页面和测试数据

  2. DFS之城堡问题

    2019-06-01 17:54:51 坚持!! 题目链接: http://bailian.openjudge.cn/practice/2815 #include <bits/stdc++.h& ...

  3. 关于C++ const 变量

    const 的全局变量是储存在一个只读数据段中,虽然你可以定义一个指向它的指针,却会在运行时,在对该地址赋值的时候发生运行错误,而局部的const变量是储存在栈中的,离开作用域后同样会被释放,并且可以 ...

  4. SRM-697-DIV2

    Div2 Medium: DivisibleSetDiv2 Problem Statement      You are given a vector <int> b containing ...

  5. C# asp.net repeater实现排序功能,自动排序,点击头部排序,点击列排序

    在网上看到好多关于repeater排序的,自己动手用了,发现一些问题,贴源码后把发现的问题以及解决方法给出 repeater实现排序功能(单击升序排列,再单击降序排列).原理很简单,在<TD&g ...

  6. 【PL/SQL】触发器示例:记录加薪

    首先创建一张表,用于保存薪资变化情况: --创建加薪记录表 CREATE TABLE scott.raisedsalarylog ( empno ) NOT NULL PRIMARY KEY, --员 ...

  7. c#——值类型与引用类型

    值类型传的是值 引用类型传的是地址

  8. Linux 一些小知识点汇总(持续更新....)

    一.符号 1.$@:传递的参数. 2.$# :传递参数的数量. 3.$?:指上一次执行命令后的返回值.一般0表示运行成功. 补充:$?只表示上一个命令执行后的退出状态,当命令执行后,又执行了其他命令, ...

  9. Centos7搭建nginx并提供外网访问

    搭建nginx之后,80端口,其他机器无法访问 查询端口是否开启 firewall-cmd --query-port=80/tcp 永久开放80端口 firewall-cmd --permanent ...

  10. 扩增子图表解读6韦恩图:比较组间共有和特有OTU或分类单元

    韦恩图 Venn Diagram Venn Diagram,也称韦恩图.维恩图.文氏图,用于显示元素集合重叠区域的图示.   韦图绘制工具 常用R语言的VennDiagram包绘制,输出PDF格式方便 ...