数字签名原理简介(附数字证书)

首先要了解什么叫对称加密和非对称加密,消息摘要这些知识。

1. 非对称加密

在通信双方,如果使用非对称加密,一般遵从这样的原则:公钥加密,私钥解密。同时,一般一个密钥加密,另一个密钥就可以解密。

因为公钥是公开的,如果用来解密,那么就很容易被不必要的人解密消息。因此,私钥也可以认为是个人身份的证明。

如果通信双方需要互发消息,那么应该建立两套非对称加密的机制(即两对公私钥密钥对),发消息的一方使用对方的公钥进行加密,接收消息的一方使用自己的私钥解密。

2.消息摘要

消息摘要可以将消息哈希转换成一个固定长度的值唯一的字符串。值唯一的意思是不同的消息转换的摘要是不同的,并且能够确保唯一。该过程不可逆,即不能通过摘要反推明文(似乎SHA1已经可以被破解了,SHA2还没有。一般认为不可破解,或者破解需要耗费太多时间,性价比低)。

利用这一特性,可以验证消息的完整性。

消息摘要通常用在数字签名中,下面介绍用法。

了解基础知识之后,就可以看一下数字签名和数字证书了。

3.数字签名

假设现在有通信双方A和B,两者之间使用两套非对称加密机制。

现在A向B发消息。

那么,如果在发送过程中,有人修改了里面密文消息,B拿到的密文,解密之后得到明文,并非A所发送的,信息不正确。

要解决两个问题:1. A的身份认证 2. A发送的消息完整性 那么就要用到上面所讲的基础知识。

数字签名的过程如下图:

简单解释:

A:将明文进行摘要运算后得到摘要(消息完整性),再将摘要用A的私钥加密(身份认证),得到数字签名,将密文和数字签名一块发给B。

B:收到A的消息后,先将密文用自己的私钥解密,得到明文。将数字签名用A的公钥进行解密后,得到正确的摘要(解密成功说明A的身份被认证了)。

对明文进行摘要运算,得到实际收到的摘要,将两份摘要进行对比,如果一致,说明消息没有被篡改(消息完整性)。

疑问:

摘要使用A的私钥加密,如果被拥有A的公钥的第三者截获,不就可以获取到摘要了么?会不会对安全造成威胁。

不会。因为摘要是不可逆推出原文的。

4.数字证书

理解了数字签名之后,数字证书就好理解了。

由于网络上通信的双方可能都不认识对方,那么就需要第三者来介绍,这就是数字证书。

数字证书由Certificate Authority( CA 认证中心)颁发。

关于数字证书的具体描述,需要百度,目前未完全理解。记一个TODO。

图解如下:

首先A B双方要互相信任对方证书。//TODO

然后就可以进行通信了,与上面的数字签名相似。不同的是,使用了对称加密。这是因为,非对称加密在解密过程中,消耗的时间远远超过对称加密。如果密文很长,那么效率就比较低下了。但密钥一般不会特别长,对对称加密的密钥的加解密可以提高效率。

数字证书简介及Java编码实现

1.数字证书简介

数字证书具备常规加密解密必要的信息,包含签名算法,可用于网络数据加密解密交互,标识网络用户(计算机)身份。数字证书为发布公钥提供了一种简便的途径,其数字证书则成为加密算法以及公钥的载体。依靠数字证书,我们可以构建一个简单的加密网络应用平台。

数字证书类似于个人身份证,由数字证书颁发认证机构(Certificate Authority, CA)签发。只有经过CA签发的证书在网络中才具备可认证性。CA颁发给自己的证书叫根证书。

VeriSign, GeoTrust和Thawte是国际权威数字证书颁发认证机构的三巨头。其中应用最广泛的是VeriSign签发的电子商务用数字证书。

最为常用的非对称加密算法是RSA,与之配套的签名算法是SHA1withRSA,最常用的消息摘要算法是SHA1.

除了RSA,还可以使用DSA算法。只是使用DSA算法无法完成加密解密实现,即这样的证书不包括加密解密功能。

数字证书有多种文件编码格式,主要包含CER编码,DER编码等。

CER(Canonical Encoding Rules, 规范编码格式),DER(Distinguished Encoding Rules 卓越编码格式),两者的区别是前者是变长模式,后者是定长模式。

所有证书都符合公钥基础设施(PKI, Public Key Infrastructure)制定的ITU-T X509国际标准(X.509标准)。

2.模型分析

在实际应用中,很多数字证书都属于自签名证书,即证书申请者为自己的证书签名。这类证书通常应用于软件厂商内部发放的产品中,或约定使用该证书的数据交互双方。数字证书完全充当加密算法的载体,为必要数据做加密解密和签名验签等操作。在我司的开发过程中,数字证书更多是用来做加密和解密。

1)证书签发

2)加密交互,图略。

当客户端获取到服务器下发的数字证书后,就可以进行加密交互了。具体做法是:

客户端使用公钥,加密后发送给服务端,服务端用私钥进行解密验证。

服务端使用私钥进行加密和数字签名。

3. KeyTool 管理证书

KeyTool与本地密钥库相关联,将私钥存于密钥库,公钥则以数字证书输出。KeyTool位于JDK目录下的bin目录中,需要通过命令行进行相应的操作。

1)构建自签名证书

申请数字证书之前,需要在密钥库中以别名的方式生成本地数字证书,建立相应的加密算法,密钥,有效期等信息。

keytool -genkeypair -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 3600 -alias myCertificate -keystore myKeystore.keystore

各参数含义如下:

-genkeypair  表示生成密钥对

-keyalg    指定密钥算法,这里是RSA

-keysize    指定密钥长度,默认1024,这里指定2048

-sigal     指定签名算法,这里是SHA1withRSA

-validity    指定有效期,单位为天

-alias     指定别名

-keystore    指定密钥库存储位置

这里我输入参数Changeme123作为密钥库的密码,也可通过参数-storepass指定密码。可以用-dname "CN=xxx...."这样的形式,避免更多交互。

注意:一个keystore应该是可以存储多套<私钥-数字证书>的信息,通过别名来区分。通过实践,调用上述命令两次(别名不同),生成同一个keystore,用不同别名进行加密解密和签名验签,没有任何问题。

更多命令可参考:http://blog.chinaunix.net/uid-17102734-id-2830223.html

经过上述操作后,密钥库中已经创建了数字证书。虽然这时的数字证书并没有经过CA认证,但并不影响我们使用。我们仍可将证书导出,发送给合作伙伴进行加密交互。

keytool -exportcert -alias myCertificate -keystore myKeystore.keystore -file myCer.cer -rfc

各参数含义如下:

-exportcert  表示证书导出操作

-alias     指定别名

-keystore   指定密钥库文件

-file      指定导出证书的文件路径

-rfc      指定以Base64编码格式输出

打印证书

keytool -printcert -file myCer.cer

2)构建CA签发证书

如果要获取CA机构谁的数字证书,需要将数字证书签发申请(CSR)导出,经由CA机构认证并颁发,将认证后的证书导入本地密钥库和信息库。

keytool -certreq -alias myCertificate -keystore myKeystore.keystore -file myCsr.csr -v

各参数含义如下:

-certreq    表示数字证书申请操作

-alias      指定别名

-keystore    指定密钥库文件路径

-file      指定导出申请的路径

-v       详细信息

获得签发的数字证书后,需要将其导入信任库。

keytool -importcert -trustcacerts -alias myCertificate -file myCer.cer -keystore myKeystore.keystore

参数不作详细讲解,如果是原来的证书文件,那么会报错:

查看证书

keytool -list -alias myCertificate -keystore myKeystore.keystore

经过上述的所有操作后,可以得到下面几个文件

4. 证书使用

终于到了激动人心的时刻,可以用代码通过keystore进行加解密操作了!

Java 6提供了完善的数字证书管理实现,我们几乎无需关注,仅通过操作密钥库和数字证书就可完成相应的加密解密和签名验签过程。

密钥库管理私钥,数字证书管理公钥,公钥和私钥分属消息传递双方,进行加密消息传递。

考虑一个场景。

A机器某模块需要将数据导出到一个文件中,将文件发送到B机器,由B将数据导入。

在这个场景中,A就相当于服务端,需要将证书给B,同时用私钥加密数据,生成签名,导出到文件中。

B相当于客户端,用收到的数字证书进行解密和验签。

package jdbc.pro.lin;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class MyCertifacate {
private static final String STORE_PASS = "abcd1234";
private static final String ALIAS = "myCertificate";
private static final String KEYSTORE_PATH = "D:\\Program Files\\Java\\jdk1.8.0_101\\bin\\myKeystore.keystore";//这个私钥可以放在硬盘的其他地方
private static final String CERT_PATH = "D:\\Program Files\\Java\\jdk1.8.0_101\\bin\\myCer.cer";//这个数字证书也可以放到硬盘的其他地方
private static final String PLAIN_TEXT = "MANUTD is the most greatest club in the world.";
/** JDK6只支持X.509标准的证书 */
private static final String CERT_TYPE = "X.509";

public static void main(String[] args) throws IOException {
/**
* 假设现在有这样一个场景 。A机器上的数据,需要加密导出,然后将导出文件放到B机器上导入。 在这个场景中,A相当于服务器,B相当于客户端
*/

/** A */
KeyStore keyStore = getKeyStore(STORE_PASS, KEYSTORE_PATH);
PrivateKey privateKey = getPrivateKey(keyStore, ALIAS, STORE_PASS);
X509Certificate certificate = getCertificateByKeystore(keyStore, ALIAS);

/** 加密和签名 */
byte[] encodedText = encode(PLAIN_TEXT.getBytes(), privateKey);
byte[] signature = sign(certificate, privateKey, PLAIN_TEXT.getBytes());

/** 现在B收到了A的密文和签名,以及A的可信任证书 */
X509Certificate receivedCertificate = getCertificateByCertPath(
CERT_PATH, CERT_TYPE);
PublicKey publicKey = getPublicKey(receivedCertificate);
byte[] decodedText = decode(encodedText, publicKey);
System.out.println("Decoded Text : " + new String(decodedText));
System.out.println("Signature is : "
+ verify(receivedCertificate, decodedText, signature));
}

/**
* 加载密钥库,与Properties文件的加载类似,都是使用load方法
*
* @throws IOException
*/
public static KeyStore getKeyStore(String storepass, String keystorePath)
throws IOException {
InputStream inputStream = null;
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
inputStream = new FileInputStream(keystorePath);
keyStore.load(inputStream, storepass.toCharArray());
return keyStore;
} catch (KeyStoreException | NoSuchAlgorithmException
| CertificateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
return null;
}

/**
* 获取私钥
*
* @param keyStore
* @param alias
* @param password
* @return
*/
public static PrivateKey getPrivateKey(KeyStore keyStore, String alias,
String password) {
try {
return (PrivateKey) keyStore.getKey(alias, password.toCharArray());
} catch (UnrecoverableKeyException | KeyStoreException
| NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

/**
* 获取公钥
*
* @param certificate
* @return
*/
public static PublicKey getPublicKey(Certificate certificate) {
return certificate.getPublicKey();
}

/**
* 通过密钥库获取数字证书,不需要密码,因为获取到Keystore实例
*
* @param keyStore
* @param alias
* @return
*/
public static X509Certificate getCertificateByKeystore(KeyStore keyStore,
String alias) {
try {
return (X509Certificate) keyStore.getCertificate(alias);
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

/**
* 通过证书路径生成证书,与加载密钥库差不多,都要用到流。
*
* @param path
* @param certType
* @return
* @throws IOException
*/
public static X509Certificate getCertificateByCertPath(String path,
String certType) throws IOException {
InputStream inputStream = null;
try {
// 实例化证书工厂
CertificateFactory factory = CertificateFactory
.getInstance(certType);
// 取得证书文件流
inputStream = new FileInputStream(path);
// 生成证书
Certificate certificate = factory.generateCertificate(inputStream);

return (X509Certificate) certificate;
} catch (CertificateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
return null;

}

/**
* 从证书中获取加密算法,进行签名
*
* @param certificate
* @param privateKey
* @param plainText
* @return
*/
public static byte[] sign(X509Certificate certificate,
PrivateKey privateKey, byte[] plainText) {
/** 如果要从密钥库获取签名算法的名称,只能将其强制转换成X509标准,JDK 6只支持X.509类型的证书 */
try {
Signature signature = Signature.getInstance(certificate
.getSigAlgName());
signature.initSign(privateKey);
signature.update(plainText);
return signature.sign();
} catch (NoSuchAlgorithmException | InvalidKeyException
| SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;
}

/**
* 验签,公钥包含在证书里面
*
* @param certificate
* @param decodedText
* @param receivedignature
* @return
*/
public static boolean verify(X509Certificate certificate,
byte[] decodedText, final byte[] receivedignature) {
try {
Signature signature = Signature.getInstance(certificate
.getSigAlgName());
/** 注意这里用到的是证书,实际上用到的也是证书里面的公钥 */
signature.initVerify(certificate);
signature.update(decodedText);
return signature.verify(receivedignature);
} catch (NoSuchAlgorithmException | InvalidKeyException
| SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}

/**
* 加密。注意密钥是可以获取到它适用的算法的。
*
* @param plainText
* @param privateKey
* @return
*/
public static byte[] encode(byte[] plainText, PrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(plainText);
} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;

}

/**
* 解密,注意密钥是可以获取它适用的算法的。
*
* @param encodedText
* @param publicKey
* @return
*/
public static byte[] decode(byte[] encodedText, PublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(encodedText);
} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;
}
}

  1. 1 package jdbc.pro.lin;
  2. 2
  3. 3 import java.io.FileInputStream;
  4. 4 import java.io.FileNotFoundException;
  5. 5 import java.io.IOException;
  6. 6 import java.io.InputStream;
  7. 7 import java.security.InvalidKeyException;
  8. 8 import java.security.KeyStore;
  9. 9 import java.security.KeyStoreException;
  10. 10 import java.security.NoSuchAlgorithmException;
  11. 11 import java.security.PrivateKey;
  12. 12 import java.security.PublicKey;
  13. 13 import java.security.Signature;
  14. 14 import java.security.SignatureException;
  15. 15 import java.security.UnrecoverableKeyException;
  16. 16 import java.security.cert.Certificate;
  17. 17 import java.security.cert.CertificateException;
  18. 18 import java.security.cert.CertificateFactory;
  19. 19 import java.security.cert.X509Certificate;
  20. 20
  21. 21 import javax.crypto.BadPaddingException;
  22. 22 import javax.crypto.Cipher;
  23. 23 import javax.crypto.IllegalBlockSizeException;
  24. 24 import javax.crypto.NoSuchPaddingException;
  25. 25
  26. 26 public class MyCertifacate {
  27. 27 private static final String STORE_PASS = "Changeme123";
  28. 28 private static final String ALIAS = "myCertificate";
  29. 29 private static final String KEYSTORE_PATH = "D:\\JavaDemo\\Certifacate\\myKeystore.keystore";
  30. 30 private static final String CERT_PATH = "D:\\JavaDemo\\Certifacate\\myCer.cer";
  31. 31 private static final String PLAIN_TEXT = "MANUTD is the most greatest club in the world.";
  32. 32 /** JDK6只支持X.509标准的证书 */
  33. 33 private static final String CERT_TYPE = "X.509";
  34. 34
  35. 35 public static void main(String[] args) throws IOException {
  36. 36 /**
  37. 37 * 假设现在有这样一个场景 。A机器上的数据,需要加密导出,然后将导出文件放到B机器上导入。 在这个场景中,A相当于服务器,B相当于客户端
  38. 38 */
  39. 39
  40. 40 /** A */
  41. 41 KeyStore keyStore = getKeyStore(STORE_PASS, KEYSTORE_PATH);
  42. 42 PrivateKey privateKey = getPrivateKey(keyStore, ALIAS, STORE_PASS);
  43. 43 X509Certificate certificate = getCertificateByKeystore(keyStore, ALIAS);
  44. 44
  45. 45 /** 加密和签名 */
  46. 46 byte[] encodedText = encode(PLAIN_TEXT.getBytes(), privateKey);
  47. 47 byte[] signature = sign(certificate, privateKey, PLAIN_TEXT.getBytes());
  48. 48
  49. 49 /** 现在B收到了A的密文和签名,以及A的可信任证书 */
  50. 50 X509Certificate receivedCertificate = getCertificateByCertPath(
  51. 51 CERT_PATH, CERT_TYPE);
  52. 52 PublicKey publicKey = getPublicKey(receivedCertificate);
  53. 53 byte[] decodedText = decode(encodedText, publicKey);
  54. 54 System.out.println("Decoded Text : " + new String(decodedText));
  55. 55 System.out.println("Signature is : "
  56. 56 + verify(receivedCertificate, decodedText, signature));
  57. 57 }
  58. 58
  59. 59 /**
  60. 60 * 加载密钥库,与Properties文件的加载类似,都是使用load方法
  61. 61 *
  62. 62 * @throws IOException
  63. 63 */
  64. 64 public static KeyStore getKeyStore(String storepass, String keystorePath)
  65. 65 throws IOException {
  66. 66 InputStream inputStream = null;
  67. 67 try {
  68. 68 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  69. 69 inputStream = new FileInputStream(keystorePath);
  70. 70 keyStore.load(inputStream, storepass.toCharArray());
  71. 71 return keyStore;
  72. 72 } catch (KeyStoreException | NoSuchAlgorithmException
  73. 73 | CertificateException | IOException e) {
  74. 74 // TODO Auto-generated catch block
  75. 75 e.printStackTrace();
  76. 76 } finally {
  77. 77 if (null != inputStream) {
  78. 78 inputStream.close();
  79. 79 }
  80. 80 }
  81. 81 return null;
  82. 82 }
  83. 83
  84. 84 /**
  85. 85 * 获取私钥
  86. 86 *
  87. 87 * @param keyStore
  88. 88 * @param alias
  89. 89 * @param password
  90. 90 * @return
  91. 91 */
  92. 92 public static PrivateKey getPrivateKey(KeyStore keyStore, String alias,
  93. 93 String password) {
  94. 94 try {
  95. 95 return (PrivateKey) keyStore.getKey(alias, password.toCharArray());
  96. 96 } catch (UnrecoverableKeyException | KeyStoreException
  97. 97 | NoSuchAlgorithmException e) {
  98. 98 // TODO Auto-generated catch block
  99. 99 e.printStackTrace();
  100. 100 }
  101. 101 return null;
  102. 102 }
  103. 103
  104. 104 /**
  105. 105 * 获取公钥
  106. 106 *
  107. 107 * @param certificate
  108. 108 * @return
  109. 109 */
  110. 110 public static PublicKey getPublicKey(Certificate certificate) {
  111. 111 return certificate.getPublicKey();
  112. 112 }
  113. 113
  114. 114 /**
  115. 115 * 通过密钥库获取数字证书,不需要密码,因为获取到Keystore实例
  116. 116 *
  117. 117 * @param keyStore
  118. 118 * @param alias
  119. 119 * @return
  120. 120 */
  121. 121 public static X509Certificate getCertificateByKeystore(KeyStore keyStore,
  122. 122 String alias) {
  123. 123 try {
  124. 124 return (X509Certificate) keyStore.getCertificate(alias);
  125. 125 } catch (KeyStoreException e) {
  126. 126 // TODO Auto-generated catch block
  127. 127 e.printStackTrace();
  128. 128 }
  129. 129 return null;
  130. 130 }
  131. 131
  132. 132 /**
  133. 133 * 通过证书路径生成证书,与加载密钥库差不多,都要用到流。
  134. 134 *
  135. 135 * @param path
  136. 136 * @param certType
  137. 137 * @return
  138. 138 * @throws IOException
  139. 139 */
  140. 140 public static X509Certificate getCertificateByCertPath(String path,
  141. 141 String certType) throws IOException {
  142. 142 InputStream inputStream = null;
  143. 143 try {
  144. 144 // 实例化证书工厂
  145. 145 CertificateFactory factory = CertificateFactory
  146. 146 .getInstance(certType);
  147. 147 // 取得证书文件流
  148. 148 inputStream = new FileInputStream(path);
  149. 149 // 生成证书
  150. 150 Certificate certificate = factory.generateCertificate(inputStream);
  151. 151
  152. 152 return (X509Certificate) certificate;
  153. 153 } catch (CertificateException | IOException e) {
  154. 154 // TODO Auto-generated catch block
  155. 155 e.printStackTrace();
  156. 156 } finally {
  157. 157 if (null != inputStream) {
  158. 158 inputStream.close();
  159. 159 }
  160. 160 }
  161. 161 return null;
  162. 162
  163. 163 }
  164. 164
  165. 165 /**
  166. 166 * 从证书中获取加密算法,进行签名
  167. 167 *
  168. 168 * @param certificate
  169. 169 * @param privateKey
  170. 170 * @param plainText
  171. 171 * @return
  172. 172 */
  173. 173 public static byte[] sign(X509Certificate certificate,
  174. 174 PrivateKey privateKey, byte[] plainText) {
  175. 175 /** 如果要从密钥库获取签名算法的名称,只能将其强制转换成X509标准,JDK 6只支持X.509类型的证书 */
  176. 176 try {
  177. 177 Signature signature = Signature.getInstance(certificate
  178. 178 .getSigAlgName());
  179. 179 signature.initSign(privateKey);
  180. 180 signature.update(plainText);
  181. 181 return signature.sign();
  182. 182 } catch (NoSuchAlgorithmException | InvalidKeyException
  183. 183 | SignatureException e) {
  184. 184 // TODO Auto-generated catch block
  185. 185 e.printStackTrace();
  186. 186 }
  187. 187
  188. 188 return null;
  189. 189 }
  190. 190
  191. 191 /**
  192. 192 * 验签,公钥包含在证书里面
  193. 193 *
  194. 194 * @param certificate
  195. 195 * @param decodedText
  196. 196 * @param receivedignature
  197. 197 * @return
  198. 198 */
  199. 199 public static boolean verify(X509Certificate certificate,
  200. 200 byte[] decodedText, final byte[] receivedignature) {
  201. 201 try {
  202. 202 Signature signature = Signature.getInstance(certificate
  203. 203 .getSigAlgName());
  204. 204 /** 注意这里用到的是证书,实际上用到的也是证书里面的公钥 */
  205. 205 signature.initVerify(certificate);
  206. 206 signature.update(decodedText);
  207. 207 return signature.verify(receivedignature);
  208. 208 } catch (NoSuchAlgorithmException | InvalidKeyException
  209. 209 | SignatureException e) {
  210. 210 // TODO Auto-generated catch block
  211. 211 e.printStackTrace();
  212. 212 }
  213. 213 return false;
  214. 214 }
  215. 215
  216. 216 /**
  217. 217 * 加密。注意密钥是可以获取到它适用的算法的。
  218. 218 *
  219. 219 * @param plainText
  220. 220 * @param privateKey
  221. 221 * @return
  222. 222 */
  223. 223 public static byte[] encode(byte[] plainText, PrivateKey privateKey) {
  224. 224 try {
  225. 225 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
  226. 226 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  227. 227 return cipher.doFinal(plainText);
  228. 228 } catch (NoSuchAlgorithmException | NoSuchPaddingException
  229. 229 | InvalidKeyException | IllegalBlockSizeException
  230. 230 | BadPaddingException e) {
  231. 231 // TODO Auto-generated catch block
  232. 232 e.printStackTrace();
  233. 233 }
  234. 234
  235. 235 return null;
  236. 236
  237. 237 }
  238. 238
  239. 239 /**
  240. 240 * 解密,注意密钥是可以获取它适用的算法的。
  241. 241 *
  242. 242 * @param encodedText
  243. 243 * @param publicKey
  244. 244 * @return
  245. 245 */
  246. 246 public static byte[] decode(byte[] encodedText, PublicKey publicKey) {
  247. 247 try {
  248. 248 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
  249. 249 cipher.init(Cipher.DECRYPT_MODE, publicKey);
  250. 250 return cipher.doFinal(encodedText);
  251. 251 } catch (NoSuchAlgorithmException | NoSuchPaddingException
  252. 252 | InvalidKeyException | IllegalBlockSizeException
  253. 253 | BadPaddingException e) {
  254. 254 // TODO Auto-generated catch block
  255. 255 e.printStackTrace();
  256. 256 }
  257. 257
  258. 258 return null;
  259. 259 }
  260. 260 }

数字签名、数字证书的原理以及证书的获得java版的更多相关文章

  1. RSA 非对称加密 数字签名 数字证书

    什么是RSA加密算法 RSA加密算法是一种非对称加密算法,算法的数学基础是极大数分解难题. RSA加密算法的强度也就是极大数分解的难度,目前700多位(二进制)的数字已经可以破解,1024位认为是比较 ...

  2. # 数字签名&数字证书

    目录 数字签名&数字证书 数字签名 数字证书 数字证书的实例(https协议) 数字签名&数字证书 参考资料: 数字签名是什么?-阮一峰的网络日志 数字签名和数字证书究竟是什么?知乎- ...

  3. HTTPS 原理与证书实践

    1.1 网络安全知识 1.1.1 网结安全出现背景 网络就是实现不同主机之间的通讯,网络出现之初利用TCP/IP协议簇的相关协议概念,已经满足了互连两台主机之间可以进行通汛的目的,虽然看似简简单单几句 ...

  4. [svc]HTTPS证书生成原理和部署细节

    参考: http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/ 今天摸索了下 HTTPS 的证书生成,以及它在 Ng ...

  5. HTTPS证书生成原理和部署细节

    看看下面,部分电信用户访问京东首页的时候,会看到右下角有一个浮动广告: 小白用户以为是京东有意放置的,细心的用户会发现,这个 iframe 一层嵌一层的恶心广告很明显是电信/中间人通过 DNS 劫持注 ...

  6. iOS推送原理和证书生成简介

    1. 推送流程: Provider: 我们自己的后台服务器: APNS: 苹果的消息推送服务器 (1) 当Provider有消息要推送给手机的时候,先将消息和deviceToken等字段发送到APNS ...

  7. CA证书理解?CA证书的作用?

    CA证书顾名思义就是由CA(Certification Authority)机构发布的数字证书.要对CA证书完全理解及其作用,首先要理解SSL.SSL(security sockets layer,安 ...

  8. [加密]证书、CA、证书信任链

    转自:https://www.jianshu.com/p/6bf2f9a37feb TLS 传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(S ...

  9. SSL、数字签名、CA 工作原理

    SSL.数字签名.CA 工作原理 对称加密和非对称加密介绍和区别 什么是对称加密技术?   对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方 ...

随机推荐

  1. VS“当前上下文中不存在名称“ViewBag”,当前上下文不存在名称“model””-已解决

    自己的项目出现了错误提示,却能编译成功,但是有点强迫症,总是想解决这个错误. 上网找了一堆,都是删除缓存等一些方法,但是没有多大用处,我觉得还是版本号不对,没有引用进来相应的配置,所以配置下了Conf ...

  2. Oracle数据库mybatis 插入空值时报错(with JdbcType OTHER)

    参考文档: 1.https://blog.csdn.net/fishernemo/article/details/27649233 2.http://helgaxu.iteye.com/blog/21 ...

  3. 简单的node 服务端 响应get,返回json数据;

    原文:http://blog.csdn.net/xn_28/article/details/50837019 const http = require('http'); const hostname ...

  4. 一个漂亮的lazarus做的pagecontrol

    厌倦了屏幕上的默认灰色?让我们来欣赏一下商业配色. 这个组件实现了高光,点睛色,描边边等效果, 再配几组色彩,应该非常不错. 基于 lazarus 1.08 大家可以上 www.fpccn.com 看 ...

  5. swift 总结

    结构体(struct)属于值类型, 当值类型的实例被声明为常量的时候,它的所有属性也就成了常量. 属于引用类型的类(class)则不一样.把一个引用类型的实例赋给一个常量后,仍然可以修改该实例的变量属 ...

  6. JSP自定义标签(标签处理器 tld文件)

    标签的形式如下,标签处理器就是处理JSP页面中的标签的属性和内容,定义好之后就跟使用JSTL一样 <标签名 属性名="属性值" 属性名="属性值"> ...

  7. [转]sqlmap使用教程

    sqlmap也是渗透中常用的一个注入工具,其实在注入工具方面,一个sqlmap就足够用了,只要你用的熟,秒杀各种工具,只是一个便捷性问题,sql注入另一方面就是手工党了,这个就另当别论了. 今天把我一 ...

  8. mysql 5.7.10 下互为主备配置

    mysql安装方法这里就不在介绍,网上有很多教程 环境介绍: A主机: win2008_x64+mysql5.7.10 64位,ip192.168.7.180 B主机: win2008_x64+mys ...

  9. (xxx.55).toFixed(1) 无法正确进位处理

    参考:https://juejin.im/post/5a11a9fef265da43284073b4?utm_medium=fe&utm_source=weixinqun 根本原因在于2.55 ...

  10. 在离线安装gazebo的时候可能在运行turtlebot_gazebo的时候会出现问题

    问题显示如下 gzserver: /build/ogre-1.9-mqY1wq/ogre-1.9-1.9.0+dfsg1/OgreMain/src/OgreRenderSystem.cpp:546: ...