文档章节

JAVA中RSA签名算法实现

吕兵阳
 吕兵阳
发布于 2017/09/10 12:00
字数 1092
阅读 47
收藏 0
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

/**
 * Created by Lb on 2017/9/10.
 */
public class RSACoder {

  //非对称加密算法
  public static final String KEY_ALGORITHM = "RSA";
  //数字签名 签名/验证算法
  public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
  //公钥
  private static final String PUBLIC_KEY = "RSAPublicKey";
  //私钥
  private static final String PRIVATE_KEY = "RSAPrivateKey";
  //RSA密钥长度默认1024位,密钥长度必须是64的倍数,范围在512-65536位之间
  private static final int KEY_SIZE = 512;

  /**
   * 私钥解密
   */
  public static byte[] decryptByPrivateKey(byte[] data, byte[] key)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    //取得私钥
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //生成私钥
    PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    //对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }

  /**
   * 公钥解密
   */
  public static byte[] decryptByPublicKey(byte[] data, byte[] key)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    //取得公钥
    X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //生成公钥
    PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
    //对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, publicKey);
    return cipher.doFinal(data);
  }

  /**
   * 公钥加密
   */
  public static byte[] encryptByPublicKey(byte[] data, byte[] key)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    //取得公钥
    X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //生成公钥
    PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
    //对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return cipher.doFinal(data);
  }


  /**
   * 私钥加密
   */
  public static byte[] encryptByPrivateKey(byte[] data, byte[] key)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    //取得私钥
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //生成私钥
    PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    //对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }

  /**
   * 取得私钥
   */
  public static byte[] getPrivateKey(Map<String, Object> keyMap)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    Key key = (Key) keyMap.get(PRIVATE_KEY);
    return key.getEncoded();
  }

  /**
   * 取得公钥
   */
  public static byte[] getPublicKey(Map<String, Object> keyMap)
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    Key key = (Key) keyMap.get(PUBLIC_KEY);
    return key.getEncoded();
  }

  /**
   * 初始化密钥
   */
  public static Map<String, Object> initKey() throws NoSuchAlgorithmException {
    //实例化密钥生成器
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
    //初始化密钥对生成器
    keyPairGenerator.initialize(KEY_SIZE);
    //生成密钥对
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    //公钥
    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    //私钥
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    //封装密钥
    Map<String, Object> keyMap = new HashMap<>();
    keyMap.put(PUBLIC_KEY, publicKey);
    keyMap.put(PRIVATE_KEY, privateKey);
    return keyMap;
  }

  /**
   * 签名
   *
   * @param data 待签名数据
   * @param privateKey 私钥
   * @return 数字签名
   */
  public static byte[] sign(byte[] data, byte[] privateKey)
      throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
    //转换私钥材料
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);
    //实例化密钥工厂
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //取私钥对象
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    //实例化Signature
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    //初始化Signature
    signature.initSign(priKey);
    //更新
    signature.update(data);
    //签名
    return signature.sign();
  }

  /**
   * 公钥校验
   *
   * @param data 待校验数据
   * @param publicKey 公钥
   * @param sign 数字签名
   * @return 校验成功返回true 失败返回false
   */
  public static boolean verify(byte[] data, byte[] publicKey, byte[] sign)
      throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
    //转换公钥材料
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
    //实例化密钥工厂
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    //生成公钥
    PublicKey pubKey = keyFactory.generatePublic(keySpec);
    //实例化Signature
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    //初始化Signature
    signature.initVerify(pubKey);
    //更新
    signature.update(data);
    //验证
    return signature.verify(sign);
  }

  /**
   * 私钥签名
   *
   * @param data 待签名数据
   * @param privateKey 私钥
   * @return 十六进行签名字符串
   */
  public static String sign(byte[] data, String privateKey)
      throws DecoderException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    byte[] sign = sign(data, getKey(privateKey));
    return Hex.encodeHexString(sign);
  }


  /**
   * 公钥校验
   *
   * @param data 待校验数据
   * @param publicKey 公钥
   * @param sign 签名
   * @return 成功返回true,失败返回false
   */
  public static boolean verify(byte[] data, String publicKey, String sign)
      throws DecoderException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    return verify(data, getKey(publicKey), Hex.decodeHex(sign.toCharArray()));
  }


  /**
   * 私钥加密
   */
  public static byte[] encryptByPrivateKey(byte[] data, String key)
      throws DecoderException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
    return encryptByPrivateKey(data, getKey(key));
  }

  /**
   * 公钥加密
   */
  public static byte[] encryptByPublicKey(byte[] data, String key)
      throws DecoderException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
    return encryptByPublicKey(data, getKey(key));
  }

  /**
   * 私钥解密
   */
  public static byte[] decryptByPrivateKey(byte[] data, String key)
      throws DecoderException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
    return decryptByPrivateKey(data, getKey(key));
  }

  /**
   * 公钥解密
   */
  public static byte[] decryptByPublicKey(byte[] data, String key)
      throws DecoderException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
    return decryptByPublicKey(data, getKey(key));
  }

  /**
   * 初始化密钥
   *
   * @return 十六进制编码密钥
   */
  public static String getPrivateKeyString(Map<String, Object> keyMap)
      throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
//    return Base64.encodeBase64String(getPrivateKey(keyMap));
    return Hex.encodeHexString(getPrivateKey(keyMap));
  }

  /**
   * 初始化密钥
   *
   * @return 十六进制编码密钥
   */
  public static String getPublicKeyString(Map<String, Object> keyMap)
      throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
//    return Base64.encodeBase64String(getPublicKey(keyMap));
    return Hex.encodeHexString(getPublicKey(keyMap));
  }

  /**
   * 获取密钥
   *
   * @param key 密钥
   * @return 密钥
   */
  public static byte[] getKey(String key) throws DecoderException {
    return Hex.decodeHex(key.toCharArray());
//    return Base64.decodeBase64(key);
  }


  public static void main(String[] args)
      throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidKeySpecException, NoSuchPaddingException, DecoderException, SignatureException {
    Map<String, Object> keyMap = RSACoder.initKey();
    //获取并打印公钥
    String publicKey = RSACoder.getPublicKeyString(keyMap);

    System.out.println("publicKey=" + publicKey);
    //获取并打印私钥
    String privateKey = RSACoder.getPrivateKeyString(keyMap);
    System.out.println("privateKey=" + privateKey);

    String inputStr = "测试加密18803696960http://www.baidu.com///xxxx";
    byte[] data = inputStr.getBytes();
    System.out.println("原文:" + inputStr);
    byte[] encodeData = RSACoder.encryptByPublicKey(data, publicKey);
    System.out.println("加密后:" + Hex.encodeHexString(encodeData));
    byte[] decodeData = RSACoder.decryptByPrivateKey(encodeData, privateKey);
    System.out.println("解密后:" + new String(decodeData));
    //私钥签名  公钥校验
    String sign = RSACoder.sign(data, privateKey);
    System.out.println("校验=" + RSACoder.verify(data, publicKey, sign));
  }
}

© 著作权归作者所有

共有 人打赏支持
吕兵阳
粉丝 88
博文 275
码字总数 105273
作品 0
郑州
后端工程师
私信 提问
Android外部文件加解密及应用实践

有这样的应用场景,当我们把一些重要文件放到asset文件夹中时,把.apk解压是可以直接拿到这个文件的,一些涉及到重要信息的文件我们并不想被反编译拿去,这个时候需要先对文件进行加密,然后...

C6C
05/08
0
0
Java结合keytool实现非对称加密和解密

原文出处:王洁 参考:Java结合keytool实现非对称签名与验证 那一篇讲签名,这一篇将加密解密。在Java安全体系中,签名属于JAAS模块,加解密属于JCE模块。 keytool的使用 keytool是JDK自带的...

王洁
08/08
0
0
【项目管理】软件项目经理须知的 Java 8 安全知识

【译者按】作为软件研发项目的项目经理,只懂项目管理知识是不够的,需要对软件技术本身有基本的了解。Java 是一种主流的系统开发语言,其安全设计对于构建安全的信息系统有至关重要的意义。...

军雷
2017/06/08
0
0
Java结合keytool实现非对称签名与验证

原文出处:王洁 参考”Oracle–The Java Tutorials: Generate Keys” 还有姊妹篇:Java结合keytool实现非对称加密和解密 keytool的使用 keytool 是 JDK 自带的一个密钥库管理工具。这里只用到...

王洁
08/09
0
0
tomcat实现SSL配置(详细版)

Tomcat双向认证的问题这么多,贴一篇我总结的Tomcat双向认证方法 tomcat实现SSL配置 tomcat实现SSL配置 编辑tomcat的配置文件server.xml,去掉下面SSL Connector的注释,修改为如下: <!-- D...

被风遗忘
2012/03/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS配置Tomcat监听80端口,虚拟主机

Tomcat更改默认端口为80 更改的配置文件是: /usr/local/tomcat/conf/server.xml [root@test-a ~]# vim /usr/local/tomcat/conf/server.xml # 找到 Connector port="8080" protocol="HTTP/1......

野雪球
16分钟前
0
0
《稻盛和夫经营学》读后感心得体会3180字范文

《稻盛和夫经营学》读后感心得体会3180字范文: 一代日本经营之圣稻盛和夫凭借刻苦勤奋的精神以及深植于佛教的商业道德准则,成为了“佛系”企业家的代表人物。在《稻盛和夫经营学》“领导人...

原创小博客
56分钟前
1
0
java框架学习日志-5(常见的依赖注入)

依赖注入(dependency injection) 之前提到控制反转(Inversion of Control)也叫依赖注入,它们其实是一个东西,只是看的角度不同,这章详细说一下依赖注入。 依赖——指bean对象创建依赖于...

白话
今天
2
0
红外接收器驱动开发

背景:使用系统的红外遥控软件没有反应,然后以为自己接线错误,反复测试,结果烧坏了一个红外接收器,信号主板没有问题。所以自己开发了一个红外接收器的python驱动。接线参见https://my.os...

mbzhong
今天
2
0
ActiveMQ消息传送机制以及ACK机制详解

AcitveMQ是作为一种消息存储和分发组件,涉及到client与broker端数据交互的方方面面,它不仅要担保消息的存储安全性,还要提供额外的手段来确保消息的分发是可靠的。 一. ActiveMQ消息传送机...

watermelon11
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部