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

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

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

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  2. iOS.Crash.OniOS8.WhenCall[popToRootViewController]

    系统iOS 8.x, ARC. CrashCase: 在UIViewController中有一个类型为UIScrollView的实例变量scrollView, 点击UIViewController中的 ...

  3. How to Solve Lonsdor K518ISE Abnormal Display by Factory Resetting

    Here’s the working solution to Lonsdor K518ISE Key Programmer abnormal display after upgrade. Proble ...

  4. UVA 11324.The Largest Clique tarjan缩点+拓扑dp

    题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相 ...

  5. 如何从平面设计转行到UI设计?

    时代的变迁,科技的进步,工具的发展,薪资的差距,促使许多人转行的原因,但平面与界面两者之间有着哪些的差异呢?如果,想要转行又该具备哪些条件呢? 平面.界面设计之间的差异性 平面设计以『视觉』为主轴,强 ...

  6. IOS初级:app的图标

    1,首先准备6张png图,分辨率一定要正确,不然报错(The app icon set named "AppIcon" did not have any applicable co ...

  7. Chrome firefox ie等浏览器空格(&nbsp;)兼容问题

    使用(&nbsp:)空格浏览器之间,显示的不一样,对不起等现象. 解决方案: 用半角空格&ensp:或者全角空格&emsp:就可以了,&ensp:相当于半格中文字符的宽 ...

  8. Reduce 和 Transduce 的含义

    一.reduce 的用法 reduce是一种数组运算,通常用于将数组的所有成员"累积"为一个值. var arr = [1, 2, 3, 4]; var sum = (a, b) ...

  9. [C#.net]处理UTF-8文件乱码

    今天帮同事处理一个2M左右的文件的格式,发现使用Encoding.default & Encoding.UTF8 & Encoding.GetEncoding("GB2312 ...

  10. Keras下的文本情感分析简介。与MLP,RNN,LSTM模型下的文本情感测试

    # coding: utf-8 # In[1]: import urllib.request import os import tarfile # In[2]: url="http://ai ...