一、签名与签验的含义

签名:客户端使用私钥对字符串加密,得到一个加密后的字符串

签验(签名验证):服务端使用公钥对字符串加密,验证加密后的字符串是否和客户端签名后一样

二、创建私钥、证书等文件

在linux中执行一下命令,生成所需的各个文件

1.手动生成私钥pri.key
openssl genrsa -des3 -passout pass:123456 -out pri.key 20482.生成pkcs8
openssl pkcs8 -topk8 -in pri.key -out pkcs8.pem -nocrypt -passin pass:1234563.生成pkcs10申请书P10.key //C国家,ST省,L市,O组织,OU部门,CN域名或ip
openssl req -new -key pri.key -passin pass:123456 -out P10.key -subj "/C=CN/ST=GUANGZHOU/L=GUANGZHOU/O=A/OU=B/CN=xxx"4.生成公钥pub.key
openssl rsa -in pri.key -passin pass:123456  -pubout -out pub.key5.生成证书server.crt
openssl x509 -req -days 365 -in P10.key -signkey pri.key -passin pass:123456  -out server.crt6.生成pk12文件
openssl pkcs12 -export -in server.crt -inkey pri.key -passin pass:123456 -passout pass:123456 -out tomcat.p127.生成keystore文件
keytool -importkeystore -v -srckeystore tomcat.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore tomcat.keystore -deststoretype jks -deststorepass 123456

以上生成的文件,我们需要用到pkcs8和server.crt

生成后的pkcs8内容如下

-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7Uv7cOJ0oCsKV
Ous6SL9GcYUlfuuZUJfJVggCYU6peL53ZKv/DzP6FSQMO8W+VRFT+nBDpLntsMBd
mnH2hP0Jz/06d8RCJhRQxn2l8/4lqAZwFhyWvd+r4bkp6nfnY4sk0/ymtC2tp31l
WgTjXKIVtMfO9Km0bNxPIV206YdC9G9IIR65NSx8AyOCmwOp3mc028+9HE/OnT5s
mw2mJB5txVUUeVZYcOq0jaNs5Z/cwzOLuaZEcTPxLHoUAbJ0cDncO6j55/8r+zZg
hkois20k4kGVDUSYKeTH2MGKc62PJVyWRYgaaE+MuU+3tGgGW+/QWR/qShpOj/VA
QDSCVM1BAgMBAAECggEBAI8T6Hg6gccY2OD03MBq2jYq9QDbvYYf6Z+tp3Zx7oxB
HnHBIiIx8YhdZ2g0q2giP5b+HYt9IUpsi7GzCsK5dzBsfcWPvwarYS8FPOlpwL/w
Y+Ju8S0uH86AHVbnsOe6v4fEpyCJVK5j1MJ6DGvA0Eh2CXuIoqqdz3RdTt6k1FyN
Wmr5xYwVq/fnG7HECWpLT1RiZZjqqU7YHlJhdRfIHLEFxsuTrBeEcl2iAt6OTYgw
4QIVJ7DQ5n7cGd2nBgodM081dA8zNrJ5833alPI04pLiu7zNM4fewZuS1ThlnG2G
rJl07IeLjZSwz9dX6Ior/xihOkOqrOqf2rQgnXJQaLECgYEA38k6ijgdGizsXWhU
qeo1TY9XzTF7kh6FWFGNsBtlPC+UmOotkF590ApitZbVnVMg1h4ruruM5Z96K/w2
jL2WahwKjTH2pT1VmsPwXra5RgWPQTEH86VD8DQvYGoIxrqaD8zlgCZuCaj6BCNZ
k6jtsV+zsK2lUUNvoVDHzm7yymUCgYEA1kobLTlu469rSE4P8KP768TWE74mQrRw
LxUTKuUnI4jr3QmMLYMDATS6pRbeUKi/KryKuZB3zqZ0qQYuUAnWVOvwjQ0qsm87
+Y9ZivGtggSGP1fpJUnuA0svvWu+u+qjB3AUO+kdXaTKMNjRySYwk2yRjmiGCTRN
N+eeUT79+60CgYEA2j9bGy/MmhmTzykP4MJsh56zh4eptwCTFWY747NkEMVqi5Nf
KnwtATcPu39GB2/qB0hXZ36/07WrpbgMz0eaqRN96uP+YnqlwRE0nHphyHtlkbOq
yKC12E5cog/nTUDxPVWbwVY5XKxyYJTFKK/IWIM4MKe5Ib694Lpyks47dM0CgYAI
89uizg118bQ3txsvYIp71SNke8M5cjRloynD1wMFlwjTmTyEAj8z47IQh54OHJ6v
+GSLUB/RQF8LWLjCm0abEahhHDW2crM8v+JrzaEEF5BMQS36YtZQyOlbro6vZyQc
gXA2+IxDh0jzNXu+PZw17IlAO9mttMOtHD4fAtS1mQKBgQCg3fuw4KyZcw4XaCCN
KlAYJhnQ5Xk79XL6xAjRyKsSG7GfE1V4tvgkHnoxnAAIPeIqxqACi/VhGXSyxH2/
cfHuXtbdcPJ5XfBnloHOZX7PLEB70SIjxy2/L1lPJUh7e7onc9QVj+PB5Wf7j3J+
bqBhY+Rk1pJ9/9Z5zU7eIN/YcA==
-----END PRIVATE KEY-----

server.crt内容如下

-----BEGIN CERTIFICATE-----
MIIDMjCCAhoCCQCs0EkSIt7T/jANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJD
TjESMBAGA1UECAwJR1VBTkdaSE9VMRIwEAYDVQQHDAlHVUFOR1pIT1UxCjAIBgNV
BAoMAUExCjAIBgNVBAsMAUIxDDAKBgNVBAMMA3h4eDAeFw0yMjAxMDcwMzI0MzNa
Fw0yMzAxMDcwMzI0MzNaMFsxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAlHVUFOR1pI
T1UxEjAQBgNVBAcMCUdVQU5HWkhPVTEKMAgGA1UECgwBQTEKMAgGA1UECwwBQjEM
MAoGA1UEAwwDeHh4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1L+
3DidKArClTrrOki/RnGFJX7rmVCXyVYIAmFOqXi+d2Sr/w8z+hUkDDvFvlURU/pw
Q6S57bDAXZpx9oT9Cc/9OnfEQiYUUMZ9pfP+JagGcBYclr3fq+G5Kep352OLJNP8
prQtrad9ZVoE41yiFbTHzvSptGzcTyFdtOmHQvRvSCEeuTUsfAMjgpsDqd5nNNvP
vRxPzp0+bJsNpiQebcVVFHlWWHDqtI2jbOWf3MMzi7mmRHEz8Sx6FAGydHA53Duo
+ef/K/s2YIZKIrNtJOJBlQ1EmCnkx9jBinOtjyVclkWIGmhPjLlPt7RoBlvv0Fkf
6koaTo/1QEA0glTNQQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBk3o9BIggMhKdX
+wEIJ3piMnwXudLC2rUs2gP4EUaW/JuOotxVB+fRGNEBeHWyx8EupKEna5ho0IuN
WoqlFKyd7luqjUItbNyQ6IWoG8+bemhXWC6zg2jrPpHvwbhb9625Oo28XgNA5lsl
Lf+ybF7wpW7gMzLVK3z+vzOnvaunbjtASde7bLmL25qfm1K08iBQUOk0+EUCXY4q
efkRrVTh1aWwVSN51QhM3lMn0wGkPl2ww34zik5dA5RzXMlrOmHoGxzmd8oAJf7g
lJIQPrFyMv+mSo54TECkWSJeRAZNa+KZ0DKskcBPgE4SDZTlkCrZa3kEganTkE5F
/SO9kc0D
-----END CERTIFICATE-----

三、在Java代码中读取这些文件,然后调用对应类进行签名和签验

public class SslUtil {/*** 签验,返回签验是否通过* @param certificate   证书* @param signStr       签名的字符串* @param unSignStr     原字符串* @return* @throws NoSuchAlgorithmException* @throws InvalidKeyException* @throws SignatureException*/public static boolean verifySign(X509Certificate certificate, String signStr, String unSignStr)throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {byte[] data = Base64.getDecoder().decode(signStr);Signature signature = Signature.getInstance(certificate.getSigAlgName());signature.initVerify(certificate.getPublicKey());signature.update(unSignStr.getBytes(StandardCharsets.UTF_8));return signature.verify(data);}/*** 使用私钥对字符串进行签名,返回Base64编码后的字符串* @param str   原始字符串* @param privateKey    私钥* @param certificate   公钥* @return* @throws NoSuchAlgorithmException* @throws InvalidKeyException* @throws SignatureException*/public static String signString(String str, PrivateKey privateKey, X509Certificate certificate)throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {Signature signature = Signature.getInstance(certificate.getSigAlgName());signature.initSign(privateKey);signature.update(str.getBytes(StandardCharsets.UTF_8));byte[] data = signature.sign();return Base64.getEncoder().encodeToString(data);}/*** 读取证书文件* @param certFile* @return* @throws CertificateException*/public static X509Certificate getCertificate(String certFile) throws CertificateException, IOException {byte[] cert = readCertFile(certFile);CertificateFactory factory = CertificateFactory.getInstance("X.509");InputStream inputStream = new ByteArrayInputStream(cert);X509Certificate certificate = (X509Certificate) factory.generateCertificate(inputStream);return certificate;}/*** 读取私钥文件* @param pkcs8File* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static PrivateKey getPrivateKey(String pkcs8File)throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {byte[] prikey = readPkcs8File(pkcs8File);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(prikey);PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** 读取私钥文件,返回字节数组* 去掉开头结尾注释行,保留中间的数据* @param pkcs8File* @return* @throws IOException*/private static byte[] readPkcs8File(String pkcs8File) throws IOException {StringBuilder stringBuilder = new StringBuilder();try(BufferedReader br = new BufferedReader(new FileReader(pkcs8File))){String line;while((line=br.readLine())!=null){if(line.startsWith("-")){continue;}stringBuilder.append(line);}return Base64.getDecoder().decode(stringBuilder.toString());}}/*** 读取Cert证书文件,返回字节数组* 把命令生成的证书文件全部读取到内存* @param certFile* @return* @throws IOException*/private static  byte[] readCertFile(String certFile) throws IOException{try(InputStream is = new FileInputStream(certFile)){return is.readAllBytes();}}
}

调用方法验证,最后会返还true

public class Main {public static void main(String[] args) {String pkcs8File = "pkcs8.pem";String certFile = "server.crt";String str = "这是原文字符串";try{PrivateKey privateKey = SslUtil.getPrivateKey(pkcs8File);X509Certificate certificate = SslUtil.getCertificate(certFile);String signStr = SslUtil.signString(str, privateKey, certificate);System.out.println("字符串 ["+str+"] ---签名--->["+signStr+"]");boolean result = SslUtil.verifySign(certificate, signStr, str);System.out.println("签验结果:"+result);}catch (Exception e){e.printStackTrace();}}
}

四、不使用java来签名,而是使用openssl命令来生成签名,然后使用java来签验

openssl签名的命令

1.创建需要签名的文件
echo "这是原文字符串" > a.txt2.对文件进行签名
openssl dgst -sha256 -passin pass:123456 -sign pri.key a.txt > b.txt3.对签名后的文件进行base64编码
base64 b.txt > c.txt/**
上面需要注意的是,不能使用openssl rsautl来生成签名
因为rsault生成的签名结果,只包含字符串body,而使用dgst生成的签名结果,是一个结构体,包含了结构体的信息(类型、长度、body)
java的Signature类解析会按照结构体进行解析,如果去解析rsault生成签名就会因为结构不对
报错javax.crypto.BadPaddingException: Decryption error
*/

命令生成的c.txt内容如下

BTG52NfjVx6v7yHq4OzCbuzeA4bvlWSPHI4N4yHSDzErmB8nWsQsJ97fKOTbeH7pdLzTuO2RS832
3wbEBo+FFTyOgUENa0J+I22SVVmCAzuPGzATRdvk6rM7kTbeMJZSIiBq/v4hX6btvAOuJ0f0/ZG5
m1bbbr3SZe26DiNl7TKgWpMhFW2OyRmaTq6fPfhOx+1/zWHFiMWrVl5WO3vJpRt2We3/wRwNzgBj
e6M+BlcQvND+gSS//ix/6avvAaNjudXU8r8/T0MKMAsuRk0zPbOjqbNudZrN4aDRf3GUkYiFzp86
5F9kkyqhapISVnpNWDEpSQz14cyoDAFUcd0yDw==

然后Java中直接拿到这个字符串进行签验

public class Main {public static void main(String[] args) {String pkcs8File = "pkcs8.pem";String certFile = "server.crt";//注意,文件方式加密的字符串,后面多了一个回车符号String str = "这是原文字符串\n";try{X509Certificate certificate = SslUtil.getCertificate(certFile);String signStr = "BTG52NfjVx6v7yHq4OzCbuzeA4bvlWSPHI4N4yHSDzErmB8nWsQsJ97fKOTbeH7pdLzTuO2RS8323wbEBo+FFTyOgUENa0J+I22SVVmCAzuPGzATRdvk6rM7kTbeMJZSIiBq/v4hX6btvAOuJ0f0/ZG5m1bbbr3SZe26DiNl7TKgWpMhFW2OyRmaTq6fPfhOx+1/zWHFiMWrVl5WO3vJpRt2We3/wRwNzgBje6M+BlcQvND+gSS//ix/6avvAaNjudXU8r8/T0MKMAsuRk0zPbOjqbNudZrN4aDRf3GUkYiFzp865F9kkyqhapISVnpNWDEpSQz14cyoDAFUcd0yDw==";boolean result = SslUtil.verifySign(certificate, signStr, str);System.out.println("签验结果:"+result);}catch (Exception e){e.printStackTrace();}}
}

使用java进行SSL证书的签名与签验相关推荐

  1. 沃通“SSL证书+代码签名证书”,防范高仿“钓鱼网站+钓鱼软件”攻击

    近日,360发布威胁预警,因监测发现多起利用钓鱼网站对特定用户进行攻击的安全事件,呼吁警惕"高仿"软件安装程序暗藏钓鱼木马."钓鱼网站+钓鱼软件"是非常典型的钓 ...

  2. java 忽略SSL证书

    ** java 忽略SSL证书 ** 代码如下:(网上借鉴了很多大神的写法,都不能实现,最终使用以下代码亲测可行,侵联删) ```java import org.apache.http.Header; ...

  3. java生成ssl证书和部署

    自签名SSL证书的生成 自签证书虽然提示:不安全.但还是有很多的好处,所以下面先说说自签证书的生成,主要使用Java JDK下的:keytool.exe 2:安装完后,根据实际的路径找到keytool ...

  4. Java管理SSL证书

    SSL证书结构 根证书的生成分为三个部分: 生成根证书的公钥和私钥 构建证书的原始证书,包括公钥.加密算法.生效时间.过期时间等信息. 用根证书私钥对原始证书进行签名,生成合法的根证书. 根证书安装, ...

  5. JAVA通过SSL证书创建MS AD账户及设置密码

    近期由于工作需要整理一下自动化的东西,因为公司去年上线了OA,所以公司的入职系统会提交用户的信息到IT部门,最早的做法是入职到了,IT部门收集用户信息在AD中创建对应的用户信息,所以为了提高管理员的工 ...

  6. jdk导入ssl证书(信任自签https证书)

    前言 工作对接EMS,给的测试地址是https. 调接口的时候发现ssl证书认证不通过,就猜测是自签的证书了 1. 导出ssl证书 浏览器输入https链接,打开后提示证书不安全. 再打开地址栏左侧不 ...

  7. python sanic 设置ssl证书_配置自签https ssl证书

    由于人们越来越重视网络安全,所以很多平台及系统都要求使用https方式接入.而且一些开源服务框架在调用时也只接受https请求,这将导致平时开发/测试时需要用到ssl证书的地方越来越多. 在2016年 ...

  8. Java生成SSL证书

    1. 背景 2. 演示环境 3. 命令 4. 创建证书 5. 查看证书 5.1. 显示详细 5.2. 编码打印 6. 导入导出证书 6.1. 导出 6.2. 导入 7. 修改密码 7.1. 修改密钥库 ...

  9. java无视ssl证书构建post/get请求【伸手党福利】

    首先上其他人写的工具类(看原理) java忽略证书验证(兼容http,https)进行get/post请求–使用(org.apache.httpcomponents httpclient客户端) ht ...

最新文章

  1. opensuse11.4 apache2 403 错误.
  2. History操作历史记录
  3. python为text添加滚动条_动态创建小部件pythontkinter并在画布中添加滚动条
  4. 用Unity3D实现简单的牧师与魔鬼游戏
  5. 刪除github上的一個repository
  6. 软件测试实验报告下载 实验一到实验五
  7. Livebos--流程结束触发事件(修改表和表里的表格字段)
  8. C#看书笔记_02 核心C#
  9. uniapp打包H5与uniapp打包apk交互,实现扫码功能。
  10. word模板生成利器poi-tl
  11. Ameya:蔡司激光共聚焦显微镜的优势特点及应用领域
  12. html怎么调用node.js,nodejs如何调用函数?
  13. [2017-08-28]Abp系列——业务异常与错误码设计及提示语的本地化
  14. centos8安装和启动中文智能拼音
  15. qsnctf 哥哥打篮球 wp
  16. UML需求分析步骤实例解析
  17. 【LeetCode】初级算法:数组
  18. BMP图片加马赛克C语言C++超简单
  19. python安装包下载及安装教程
  20. 输入某年某月某日,判断这一天是这一年的第几天?(JS实现)

热门文章

  1. Android城市列表
  2. TEB算法2-teb参数说明及调试小记
  3. 从零开始学C语言 : 初阶指针
  4. 网络直播电视之M3U8解析篇 (下)
  5. 数字电路实验 07 - | 计数器及其应用
  6. mysql介绍(myisam)
  7. foobar2000-new
  8. openpyxl的基本使用
  9. 【AVL树】AVL树的插入操作以及旋转
  10. Grid Control一些术语GC、OMS、OMR、OMA的概念