文档章节

JAVA中RSA签名算法实现

吕兵阳
 吕兵阳
发布于 2017/09/10 12:00
字数 1092
阅读 30
收藏 0
点赞 0
评论 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));
  }
}

© 著作权归作者所有

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

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

C6C ⋅ 05/08 ⋅ 0

浅入浅出 Android 安全:第六章 Android 安全的其它话题

第六章 Android 安全的其它话题 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 在本章中,我们会涉及到与 Android 安全相关的其他主题,这些主题不直接属于已经...

apachecn_飞龙 ⋅ 2016/12/02 ⋅ 0

Android JNI学习(三)——Java与Native相互调用

本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Native相互调用 Android JNI学习(四)——JNI的常用方法...

隔壁老李头 ⋅ 05/09 ⋅ 0

Java开发必须要掌握的加密方式。

第一种类型加密方式:数字摘要(不可逆) 数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash函数对消息进行计算而产生。 注:这个串有固定的长度,且不...

java高级架构牛人 ⋅ 06/12 ⋅ 0

《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

⋅ 05/05 ⋅ 0

Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区 ⋅ 05/09 ⋅ 0

「游戏引擎Mojoc」(10)Android NDK通用JNI调用Java代码封装

Mojoc提供了一个通用的工具类,来调用Android Java代码,以实现特定平台的功能。这个工具类封装了JNI使用的繁琐细和上下文对象的获取,提供了简单直接的API专注于Java类和方法的访问,并且实...

scottcgi ⋅ 05/20 ⋅ 0

java加密解密与数字证书的操作

1 Java程序实现密钥库的维护 1.1 Java程序列出密钥库所有条目 import java.util.; import java.io.; import java.security.*; public class ShowAlias{ public static void main(String arg......

happyhuangjinjin ⋅ 04/24 ⋅ 0

叮!您收到一份超值Java基础入门资料!

摘要:Java语言有什么特点?如何最大效率的学习?深浅拷贝到底有何区别?阿里巴巴高级开发工程师为大家带来Java系统解读,带你掌握Java技术要领,突破重点难点,入门面向对象编程,以详细示例...

聒小小噪 ⋅ 05/12 ⋅ 0

SpringBoot 整合 oauth2(五)实现 jwt 及 扩展

什么是jwt,即 json web token。JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。也是一种token,但是和token有一些不同。 jwt优点: 自包含 防篡改 可自定义扩展 JW...

FantJ ⋅ 05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

HiSDP —— 高效的C++软件开发平台

目前阿里集团每天有近1000PB的数据是通过LogAgent采集的,为了让LogAgent做到资源占用节省和高效采集,背后是基于HiSDP去构建的。 缘由 当决定采用C++编程语言去开发一个软件时,紧接着所面临...

阿里云云栖社区 ⋅ 6分钟前 ⋅ 0

zookeeper-3.4.12 下载与安装教程

一、zookeeper下载地址 http://mirrors.hust.edu.cn/apache/zookeeper/ 二、启动教程 把压缩包放在指定目录下 第三: 进入 conf文件夹底下 zoo_sample.cfg 文件名改成 zoo.cfg 第四步: 进入b...

泉天下 ⋅ 8分钟前 ⋅ 0

Oracle 中文日期转换

SELECT TO_date('2011年11月11日', 'yy"年"mm"月"dd"日"') FROM DUAL; 1. Oracle无法识别中文格式,所以添加双引号。 2. 后面的格式是指字符串在转换前的格式,而不是指转换后的格式。...

名侦探柯南 ⋅ 9分钟前 ⋅ 0

MySell:API Spring Boot

起步 类目 商品 订单

BeanHo ⋅ 12分钟前 ⋅ 0

Spring方法拦截器MethodInterceptor

参考资料 1、Spring方法拦截器MethodInterceptor 2、Sharding JDBC源码分析-JdbcMethodInvocation类的作用

哎小艾 ⋅ 15分钟前 ⋅ 0

正则表达式

元字符 元字符,又叫字符集,就是用一些特殊符号表示特定种类的字符或位置。 匹配字符 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 匹配...

wangchen1999 ⋅ 15分钟前 ⋅ 0

数据库数据导入Elasticsearch案例分享

基于bboss持久层和bboss elasticsearch客户端实现数据库数据导入es案例分享(支持各种数据库和各种es版本) 1.案例对应的源码 https://gitee.com/bboss/bboss-elastic/blob/master/bboss-el...

bboss ⋅ 16分钟前 ⋅ 0

动手---sbt(2)

参考 https://blog.csdn.net/leishangwen/article/details/46225587 建立一个chisel_max目录,文件内容如后面所述,现在开始执行命令: joe@joe-Aspire-Z3730:/media/sdb4/download/scala$ c......

whoisliang ⋅ 22分钟前 ⋅ 0

纯js实现最简单的文件上传(后台使用MultipartFile)

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>XMLHttpRequest上传文件</title> <script type="text/javascript"> //图片上传 var xhr......

孟飞阳 ⋅ 27分钟前 ⋅ 0

iOS宇宙大战游戏、调试工具、各种动画、AR相册、相机图片编辑等源码

iOS精选源码 日期时间选择器,swift Space Battle 宇宙大战 SpriteKit游戏源码 LLDebugTool - 便捷的IOS调试工具(新增截屏功能) 相机扫描or长按识别二维码、FMDB、键盘动态高度、定位等 动画...

sunnyaigd ⋅ 28分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部