博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基於數字證書的數據加密算法
阅读量:6091 次
发布时间:2019-06-20

本文共 17074 字,大约阅读时间需要 56 分钟。

1 package com.ice.webos.util.security;   2   3 import java.io.DataInputStream;   4 import java.io.FileInputStream;   5 import java.io.InputStream;   6 import java.net.URL;   7 import java.security.KeyStore;   8 import java.security.PrivateKey;   9 import java.security.PublicKey;  10 import java.security.Signature;  11 import java.security.cert.Certificate;  12 import java.security.cert.CertificateFactory;  13 import java.security.cert.X509Certificate;  14 import java.util.Date;  15  16 import javax.crypto.Cipher;  17 import javax.net.ssl.HttpsURLConnection;  18 import javax.net.ssl.KeyManagerFactory;  19 import javax.net.ssl.SSLContext;  20 import javax.net.ssl.SSLSocketFactory;  21 import javax.net.ssl.TrustManagerFactory;  22  23 /**  24  * 证书的制作,导入,删除  25  * 
    26 *
  • 生成keyStroe文件
  • 27 *
      28 *
    • keytool -genkey -validity 36000 -alias 192.168.20.230 -keyalg RSA 29 * -keystore d:\zlex.keystore
    • 30 *
        31 * 参数说明 32 *
      • -genkey表示生成密钥
      • 33 *
      • -validity指定证书有效期,这里是36000天
      • 34 *
      • -alias指定别名,这里是192.168.20.230
      • 35 *
      • -keyalg指定算法,这里是RSA
      • 36 *
      • -keystore指定存储位置,这里是d:\zlex.keystore
      • 37 *
      38 *
    39 *
  • 生成自签名证书
  • 40 *
      41 *
    • keytool -export -keystore d:\zlex.keystore -alias 192.168.20.230 -file 42 * d:\zlex.cer -rfc
    • 43 *
        44 * 参数说明 45 *
      • -export指定为导出操作
      • 46 *
      • -keystore指定keystore文件
      • 47 *
      • -alias指定导出keystore文件中的别名
      • 48 *
      • -file指向导出路径
      • 49 *
      • -rfc以文本格式输出,也就是以BASE64编码输出
      • 50 *
      51 *
    52 *
  • 证书导入到密钥库
  • 53 *
      54 *
    • keytool -import -alias 192.168.20.230 -file d:/zlex.cer -keystore 55 * d:/zlex.keystore
    • 56 *
        57 * 参数说明 58 *
      • -import表示导入
      • 59 *
      • -alias指定别名,这里是192.168.20.230
      • 60 *
      • -file指定算法,这里是d:/zlex.cer
      • 61 *
      • -keystore指定存储位置,这里是d:/zlex.keystore
      • 62 *
      63 *
    64 *
  • 配置tomcat
  • 65 *
      66 *
    • 将zlex.keystore拷贝到tomcat的conf目录下
    • 67 *
    • 配置server.xml。将如下内容加入配置文件
      68 * <Connector SSLEnabled="true" URIEncoding="UTF-8" clientAuth="false" 69 * keystoreFile="conf/zlex.keystore" keystorePass="654321" maxThreads="150" 70 * port="443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS" /> 71 *
    • 72 *
    • clientAuth="false"测试阶段,置为false,正式使用时建议使用true
    • 73 *
    • 启动tomcat,访问https://192.168.20.230
    • 74 *
    • 75 *
    76 *
  • 证书的删除
  • 77 *
      78 *
    • 命令行中输入 certmgr.msc
    • 79 *
    • 找到安装的证书,删除即可
    • 80 *
    81 *
82 * 83 * @author Ice_Liu 84 * 85 */ 86 public class Certificateutil {
87 /** 88 * Java密钥库(Java Key Store,JKS)KEY_STORE 89 */ 90 public static final String KEY_STORE = "JKS"; 91 92 public static final String X509 = "X.509"; 93 public static final String SunX509 = "SunX509"; 94 public static final String SSL = "SSL"; 95 96 /** 97 * 由 KeyStore获得私钥 98 * 99 * @param keyStorePath 100 * @param alias 101 * @param password 102 * @return 103 * @throws Exception 104 */ 105 private static PrivateKey getPrivateKey(String keyStorePath, String alias, String password) 106 throws Exception {
107 KeyStore ks = getKeyStore(keyStorePath, password); 108 PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray()); 109 return key; 110 } 111 112 /** 113 * 由 Certificate获得公钥 114 * 115 * @param certificatePath 116 * @return 117 * @throws Exception 118 */ 119 private static PublicKey getPublicKey(String certificatePath) throws Exception {
120 Certificate certificate = getCertificate(certificatePath); 121 PublicKey key = certificate.getPublicKey(); 122 return key; 123 } 124 125 /** 126 * 获得Certificate 127 * 128 * @param certificatePath 129 * @return 130 * @throws Exception 131 */ 132 private static Certificate getCertificate(String certificatePath) throws Exception {
133 CertificateFactory certificateFactory = CertificateFactory.getInstance(X509); 134 FileInputStream in = new FileInputStream(certificatePath); 135 136 Certificate certificate = certificateFactory.generateCertificate(in); 137 in.close(); 138 139 return certificate; 140 } 141 142 /** 143 * 获得Certificate 144 * 145 * @param keyStorePath 146 * @param alias 147 * @param password 148 * @return 149 * @throws Exception 150 */ 151 private static Certificate getCertificate(String keyStorePath, String alias, String password) 152 throws Exception {
153 KeyStore ks = getKeyStore(keyStorePath, password); 154 Certificate certificate = ks.getCertificate(alias); 155 156 return certificate; 157 } 158 159 /** 160 * 获得KeyStore 161 * 162 * @param keyStorePath 163 * @param password 164 * @return 165 * @throws Exception 166 */ 167 private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
168 FileInputStream is = new FileInputStream(keyStorePath); 169 KeyStore ks = KeyStore.getInstance(KEY_STORE); 170 ks.load(is, password.toCharArray()); 171 is.close(); 172 return ks; 173 } 174 175 /** 176 * 私钥加密 177 * 178 * @param data 179 * @param keyStorePath 180 * @param alias 181 * @param password 182 * @return 183 * @throws Exception 184 */ 185 public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, 186 String password) throws Exception {
187 // 取得私钥 188 PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password); 189 190 // 对数据加密 191 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); 192 cipher.init(Cipher.ENCRYPT_MODE, privateKey); 193 194 return cipher.doFinal(data); 195 196 } 197 198 /** 199 * 私钥解密 200 * 201 * @param data 202 * @param keyStorePath 203 * @param alias 204 * @param password 205 * @return 206 * @throws Exception 207 */ 208 public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath, String alias, 209 String password) throws Exception {
210 // 取得私钥 211 PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password); 212 213 // 对数据加密 214 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); 215 cipher.init(Cipher.DECRYPT_MODE, privateKey); 216 217 return cipher.doFinal(data); 218 219 } 220 221 /** 222 * 公钥加密 223 * 224 * @param data 225 * @param certificatePath 226 * @return 227 * @throws Exception 228 */ 229 public static byte[] encryptByPublicKey(byte[] data, String certificatePath) throws Exception {
230 231 // 取得公钥 232 PublicKey publicKey = getPublicKey(certificatePath); 233 // 对数据加密 234 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); 235 cipher.init(Cipher.ENCRYPT_MODE, publicKey); 236 237 return cipher.doFinal(data); 238 239 } 240 241 /** 242 * 公钥解密 243 * 244 * @param data 245 * @param certificatePath 246 * @return 247 * @throws Exception 248 */ 249 public static byte[] decryptByPublicKey(byte[] data, String certificatePath) throws Exception {
250 // 取得公钥 251 PublicKey publicKey = getPublicKey(certificatePath); 252 253 // 对数据加密 254 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); 255 cipher.init(Cipher.DECRYPT_MODE, publicKey); 256 257 return cipher.doFinal(data); 258 259 } 260 261 /** 262 * 验证Certificate 263 * 264 * @param certificatePath 265 * @return 266 */ 267 public static boolean verifyCertificate(String certificatePath) {
268 return verifyCertificate(new Date(), certificatePath); 269 } 270 271 /** 272 * 验证Certificate是否过期或无效 273 * 274 * @param date 275 * @param certificatePath 276 * @return 277 */ 278 public static boolean verifyCertificate(Date date, String certificatePath) {
279 boolean status = true; 280 try {
281 // 取得证书 282 Certificate certificate = getCertificate(certificatePath); 283 // 验证证书是否过期或无效 284 status = verifyCertificate(date, certificate); 285 } catch (Exception e) {
286 status = false; 287 } 288 return status; 289 } 290 291 /** 292 * 验证证书是否过期或无效 293 * 294 * @param date 295 * @param certificate 296 * @return 297 */ 298 private static boolean verifyCertificate(Date date, Certificate certificate) {
299 boolean status = true; 300 try {
301 X509Certificate x509Certificate = (X509Certificate) certificate; 302 x509Certificate.checkValidity(date); 303 } catch (Exception e) {
304 status = false; 305 } 306 return status; 307 } 308 309 /** 310 * 签名 311 * 312 * @param keyStorePath 313 * @param alias 314 * @param password 315 * 316 * @return 317 * @throws Exception 318 */ 319 public static String sign(byte[] sign, String keyStorePath, String alias, String password) 320 throws Exception {
321 // 获得证书 322 X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, 323 password); 324 // 获取私钥 325 KeyStore ks = getKeyStore(keyStorePath, password); 326 // 取得私钥 327 PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray()); 328 329 // 构建签名 330 Signature signature = Signature.getInstance(x509Certificate.getSigAlgName()); 331 signature.initSign(privateKey); 332 signature.update(sign); 333 return CryptUtil.encryptBASE64(signature.sign()); 334 } 335 336 /** 337 * 验证签名 338 * 339 * @param data 340 * @param sign 341 * @param certificatePath 342 * @return 343 * @throws Exception 344 */ 345 public static boolean verify(byte[] data, String sign, String certificatePath) throws Exception {
346 // 获得证书 347 X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath); 348 // 获得公钥 349 PublicKey publicKey = x509Certificate.getPublicKey(); 350 // 构建签名 351 Signature signature = Signature.getInstance(x509Certificate.getSigAlgName()); 352 signature.initVerify(publicKey); 353 signature.update(data); 354 355 return signature.verify(CryptUtil.decryptBASE64(sign)); 356 357 } 358 359 /** 360 * 验证Certificate 361 * 362 * @param keyStorePath 363 * @param alias 364 * @param password 365 * @return 366 */ 367 public static boolean verifyCertificate(Date date, String keyStorePath, String alias, 368 String password) {
369 boolean status = true; 370 try {
371 Certificate certificate = getCertificate(keyStorePath, alias, password); 372 status = verifyCertificate(date, certificate); 373 } catch (Exception e) {
374 status = false; 375 } 376 return status; 377 } 378 379 /** 380 * 验证Certificate 381 * 382 * @param keyStorePath 383 * @param alias 384 * @param password 385 * @return 386 */ 387 public static boolean verifyCertificate(String keyStorePath, String alias, String password) {
388 return verifyCertificate(new Date(), keyStorePath, alias, password); 389 } 390 391 /** 392 * 获得SSLSocektFactory 393 * 394 * @param password 395 * 密码 396 * @param keyStorePath 397 * 密钥库路径 398 * 399 * @param trustKeyStorePath 400 * 信任库路径 401 * @return 402 * @throws Exception 403 */ 404 private static SSLSocketFactory getSSLSocketFactory(String password, String keyStorePath, 405 String trustKeyStorePath) throws Exception {
406 // 初始化密钥库 407 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SunX509); 408 KeyStore keyStore = getKeyStore(keyStorePath, password); 409 keyManagerFactory.init(keyStore, password.toCharArray()); 410 411 // 初始化信任库 412 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SunX509); 413 KeyStore trustkeyStore = getKeyStore(trustKeyStorePath, password); 414 trustManagerFactory.init(trustkeyStore); 415 416 // 初始化SSL上下文 417 SSLContext ctx = SSLContext.getInstance(SSL); 418 ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 419 SSLSocketFactory sf = ctx.getSocketFactory(); 420 421 return sf; 422 } 423 424 /** 425 * 为 HttpsURLConnection配置SSLSocketFactory 426 * 427 * @param conn 428 * HttpsURLConnection 429 * @param password 430 * 密码 431 * @param keyStorePath 432 * 密钥库路径 433 * 434 * @param trustKeyStorePath 435 * 信任库路径 436 * @throws Exception 437 */ 438 public static void configSSLSocketFactory(HttpsURLConnection conn, String password, 439 String keyStorePath, String trustKeyStorePath) throws Exception {
440 conn.setSSLSocketFactory(getSSLSocketFactory(password, keyStorePath, trustKeyStorePath)); 441 } 442 443 /** 444 * @param args 445 * @throws Exception 446 */ 447 public static void main(String[] args) throws Exception {
448 String password = "123456"; 449 String alias = "192.168.20.230"; 450 String certificatePath = "d:/zlex.cer"; 451 String keyStorePath = "d:/zlex.keystore"; 452 String clientKeyStorePath = keyStorePath;//"d:/zlex-client.keystore"; 453 String clientPassword = "123456"; 454 455 System.err.println("公钥加密——私钥解密"); 456 String inputStr = "Ceritifcate"; 457 byte[] data = inputStr.getBytes(); 458 459 byte[] encrypt = Certificateutil.encryptByPublicKey(data, certificatePath); 460 461 byte[] decrypt = Certificateutil 462 .decryptByPrivateKey(encrypt, keyStorePath, alias, password); 463 String outputStr = new String(decrypt); 464 465 System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); 466 // 验证证书有效 467 System.out.println("验证证书有效:" + Certificateutil.verifyCertificate(certificatePath)); 468 469 System.out.println("**********************************************"); 470 System.err.println("私钥加密——公钥解密"); 471 472 inputStr = "sign"; 473 data = inputStr.getBytes(); 474 475 byte[] encodedData = Certificateutil.encryptByPrivateKey(data, keyStorePath, alias, 476 password); 477 478 byte[] decodedData = Certificateutil.decryptByPublicKey(encodedData, certificatePath); 479 480 outputStr = new String(decodedData); 481 System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); 482 483 System.err.println("私钥签名——公钥验证签名"); 484 // 产生签名 485 String sign = Certificateutil.sign(encodedData, keyStorePath, alias, password); 486 System.err.println("签名:\r" + sign); 487 488 // 验证签名 489 boolean status = Certificateutil.verify(encodedData, sign, certificatePath); 490 System.err.println("状态:\r" + status); 491 492 System.out.println("*****************************************************"); 493 URL url = new URL("https://" + alias + ":18433/webos"); 494 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 495 496 conn.setDoInput(true); 497 conn.setDoOutput(true); 498 499 Certificateutil.configSSLSocketFactory(conn, clientPassword, clientKeyStorePath, 500 clientKeyStorePath); 501 502 InputStream is = conn.getInputStream(); 503 504 int length = conn.getContentLength(); 505 506 DataInputStream dis = new DataInputStream(is); 507 data = new byte[length]; 508 dis.readFully(data); 509 510 dis.close(); 511 System.err.println(new String(data)); 512 conn.disconnect(); 513 514 } 515 }

 取得私匙和公匙的方法:

        KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("client", new KeyStore.PasswordProtection(password.toCharArray()));

        privateKey = pkEntry.getPrivateKey();
   publicKey = certificate.getPublicKey();

這種取法 私匙和公匙一定是成對的。

上邊代碼裏的取法,私匙和公匙 如果使用 特殊證書的情況下會不成對。

转载地址:http://akmwa.baihongyu.com/

你可能感兴趣的文章
阿里云产品
查看>>
ESXi磁盘块大小设立
查看>>
我的友情链接
查看>>
elasticsearch 使用事项
查看>>
sqlserver中text与Varchar(max)的区别
查看>>
Docker私有仓库Registry的搭建验证
查看>>
企业信息化-之成立信息化专项小组
查看>>
jQuery 知识点总结
查看>>
php 正则对于中文汉字字符的提取
查看>>
微服务架构—优雅停机方案
查看>>
推荐决策 对比user-based 和item-based推荐算法
查看>>
必不可少需要掌握的嵌入式知识(1) -- 网络编程
查看>>
android蓝牙打印
查看>>
ViewPager+Fragment取消预加载(延迟加载)
查看>>
Confluence 6 缓存性能优化
查看>>
八评腾讯:解密腾讯的中年危机
查看>>
我的友情链接
查看>>
iOS NSFileManeger 计算文件是否超时,和计算文件夹下文件的总大小
查看>>
Oracle DG 之--DG Broker 配置
查看>>
AIX删除多余的默认网关
查看>>