1#消息摘要算法

MessageDigest,支持MD2,MD5,SHA-1(SHA),SHA-256,SHA-384,SHA-512
6种消息摘要算法,不区分大小写

  1. byte[] input = "caishuzhan".getBytes();
  2. try {
  3. MessageDigest messageDigest = MessageDigest.getInstance("SHA");
  4. messageDigest.update(input);
  5. byte[] digest = messageDigest.digest();
  6. } catch (NoSuchAlgorithmException e) {
  7. e.printStackTrace();
  8. }

以输入流的方式去获取摘要DigestInputStream

  1. byte[] input = "caishuzhan".getBytes();
  2. try {
  3. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
  4. DigestInputStream stream = new DigestInputStream(new ByteArrayInputStream(input), messageDigest);
  5. int read = stream.read(input, 0, input.length);
  6. byte[] digest = stream.getMessageDigest().digest();
  7. stream.close();
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }

以输出流的方式更改要加密的源数据DigestOnputStream

  1. byte[] input = "caishuzhan".getBytes();
  2. try {
  3. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
  4. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  5. DigestOutputStream stream = new DigestOutputStream(outputStream, messageDigest);
  6. stream.write(input);
  7. byte[] digest = stream.getMessageDigest().digest();
  8. stream.flush();
  9. stream.close();
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }

2#算法参数

  1. try {
  2. AlgorithmParameterGenerator generator = AlgorithmParameterGenerator.getInstance("DSA");
  3. generator.init(512);
  4. AlgorithmParameters parameters = generator.generateParameters();
  5. byte[] bytes = parameters.getEncoded();
  6. AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
  7. BigInteger bigInteger = new BigInteger(bytes);
  8. ap.init(bigInteger.toByteArray());
  9. byte[] encoded = ap.getEncoded();
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }

3#KeyPair,非堆称加密的密钥对,java7提供了DH,ECDH,RSA,ECDSA,DSA等多种非对称加密和签名算法的实现,如构建DH密钥对时,密钥的长度要求为64位的倍数,范围为512-1024,默认长度为1024.生成一个DSA密钥对:

  1. try {
  2. KeyPairGenerator generator = KeyPairGenerator.getInstance("DSA");
  3. generator.initialize(1024);
  4. KeyPair keyPair = generator.generateKeyPair();
  5. } catch (Exception e) {
  6. e.printStackTrace();
  7. }

构建密钥对与还原密钥

  1. try {
  2. KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
  3. generator.initialize(1024);
  4. KeyPair keyPair = generator.generateKeyPair();
  5. byte[] bytes = keyPair.getPrivate().getEncoded();
  6. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
  7. KeyFactory factory = KeyFactory.getInstance("RSA");
  8. PrivateKey privateKey = factory.generatePrivate(keySpec);
  9. System.out.println("isEquels " +MessageDigest.isEqual(privateKey.getEncoded(),bytes));
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }

结合随机数对象构建对称密钥,Java 7 支持AES密钥长度128,192,256位

  1. KeyGenerator generator = KeyGenerator.getInstance("DES");
  2. generator.init(56,new SecureRandom());
  3. SecretKey secretKey = generator.generateKey();

4#Signature签名,数字签名算法主要包括RSA,DSA,ECDSA三种,生成签名与验证

  1. byte[] data = "caishuzhan".getBytes();
  2. KeyPairGenerator dsa = KeyPairGenerator.getInstance("DSA");
  3. dsa.initialize(1024);
  4. KeyPair keyPair = dsa.generateKeyPair();
  5. Signature signature = Signature.getInstance(dsa.getAlgorithm());
  6. signature.initSign(keyPair.getPrivate());
  7. signature.update(data);
  8. byte[] sign = signature.sign();
  9. signature.initVerify(keyPair.getPublic());
  10. signature.update(data);
  11. boolean verify = signature.verify(sign);

利用SignedObject生成签名与验证

  1. byte[] data = "caishuzhan".getBytes();
  2. KeyPairGenerator rsa = KeyPairGenerator.getInstance("DSA");
  3. rsa.initialize(1024);
  4. KeyPair keyPair = rsa.generateKeyPair();
  5. Signature signature = Signature.getInstance(rsa.getAlgorithm());
  6. SignedObject signedObject = new SignedObject(data,keyPair.getPrivate(),signature);
  7. byte[] sign = signedObject.getSignature();
  8. boolean verify = signedObject.verify(keyPair.getPublic(), signature);

数字时间戳Timestamp

  1. CertificateFactory factory = CertificateFactory.getInstance("X509");
  2. CertPath certPath = factory.generateCertPath(new FileInputStream(""));
  3. Timestamp timestamp = new Timestamp(new Date(),certPath);

5#KeyStore用于存储密钥和证书,从keyStore里根据别名获取私钥

  1. FileInputStream is = new FileInputStream("/Users/caishuzhan/Desktop/workspace/Awards/app/YHGJ.jks");
  2. KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  3. keyStore.load(is,"123456".toCharArray());
  4. is.close();
  5. PrivateKey privateKey = (PrivateKey) keyStore.getKey("123456","123456".toCharArray());
  6. //或者
  7. KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry("123456",new KeyStore.PasswordProtection("123456".toCharArray()));
  8. PrivateKey entryPrivateKey = entry.getPrivateKey();

6#Mac,安全消息摘要算法,区别与MessageDigest,需要有一个共享的密钥来生成,支持HmacMD5,

HmacSHA1,HmacSHA256,HmacSHA384,HmacSHA512 5种消息摘要算法

  1. byte[] data = "caishuzhan".getBytes();
  2. KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
  3. SecretKey secretKey = keyGenerator.generateKey();
  4. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
  5. mac.init(secretKey);
  6. byte[] bytes = mac.doFinal(data);

7#SecretKeyFactory,密钥工厂,用于生产密钥,用于byte数组还原成密钥对象

  1. KeyGenerator generator = KeyGenerator.getInstance("DES");
  2. SecretKey secretKey = generator.generateKey();
  3. byte[] encoded = secretKey.getEncoded();
  4. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(secretKey.getAlgorithm());
  5. SecretKey key = keyFactory.generateSecret(new DESKeySpec(encoded));

8#加解密的核心Cipher,参数transformation的格式“算法/工作模式/填充模式”,不同的算法支持不同的工作模式和填充模式

  1. byte[] data = "caishuzhan".getBytes();
  2. KeyGenerator generator = KeyGenerator.getInstance("DES");
  3. SecretKey secretKey = generator.generateKey();
  4. Cipher cipher = Cipher.getInstance("DES");
  5. //cipher.init(Cipher.WRAP_MODE,secretKey);
  6. //byte[] wrap = cipher.wrap(secretKey);
  7. // cipher.init(Cipher.UNWRAP_MODE,secretKey);
  8. // Key key = cipher.unwrap(wrap, "DES", Cipher.SECRET_KEY);
  9. cipher.init(Cipher.ENCRYPT_MODE,secretKey);
  10. byte[] doFinal = cipher.doFinal(data);
  11. cipher.init(Cipher.DECRYPT_MODE,secretKey);
  12. byte[] aFinal = cipher.doFinal(doFinal);

CipherInputStream和CipherOutputStream把加密内容序列化和反序列化

  1. File file = new File("/Users/caishuzhan/Desktop/cipher.txt");
  2. if (!file.exists()){
  3. file.createNewFile();
  4. }
  5. String data = "caishuzhan";
  6. KeyGenerator generator = KeyGenerator.getInstance("DES");
  7. SecretKey secretKey = generator.generateKey();
  8. Cipher cipher = Cipher.getInstance("DES");
  9. cipher.init(Cipher.ENCRYPT_MODE,secretKey);
  10. CipherOutputStream outputStream = new CipherOutputStream(new FileOutputStream(file),cipher);
  11. DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
  12. dataOutputStream.writeUTF(data);
  13. dataOutputStream.flush();
  14. dataOutputStream.close();
  15. cipher.init(Cipher.DECRYPT_MODE,secretKey);
  16. CipherInputStream inputStream = new CipherInputStream(new FileInputStream(file),cipher);
  17. DataInputStream dataInputStream = new DataInputStream(inputStream);
  18. String s = dataInputStream.readUTF();
  19. dataInputStream.close();

9#KeySpec,密钥规范,用于还原公私钥和对称密钥,X509EncodedKeySpec用于非对称的公钥构建,PKCS8EncodedKeySpec用于非对称的私钥构建,SecretKeySpec用于对称密钥构建,DESKeySpec指定DES算法,DESedeKeySpec指定三重DES加密算法,PBEKeySpec指定PBE算法

  1. KeyGenerator generator = KeyGenerator.getInstance("DES");
  2. SecretKey secretKey = generator.generateKey();
  3. byte[] encoded = secretKey.getEncoded();
  4. SecretKey key = new SecretKeySpec(encoded,secretKey.getAlgorithm());

10#证书Certificate,关于数字证书,其实就是机构给网站的一张可用凭证,用来表明发送者是否为真正的发送者,里面有传输时用到的公钥,如下

image.png

加载证书

  1. CertificateFactory factory =CertificateFactory.getInstance("X.509");
  2. FileInputStream fileInputStream = new FileInputStream("");
  3. Certificate certificate = factory.generateCertificate(fileInputStream);
  4. fileInputStream.close();

构建证书签名

  1. KeyStore keyStore = KeyStore.getInstance("jks");
  2. keyStore.load(new FileInputStream("D://test.jks"),"123456".toCharArray());
  3. X509Certificate certificate = (X509Certificate) keyStore.getCertificate("alias");
  4. Signature signature = Signature.getInstance(certificate.getSigAlgName());

证书撤销列表CRL,用与验证证书是否被撤销或者无效

  1. CertificateFactory factory = CertificateFactory.getInstance("X.509");
  2. FileInputStream fileInputStream = new FileInputStream("");
  3. Certificate certificate = factory.generateCertificate(fileInputStream);
  4. CRL crl = factory.generateCRL(fileInputStream);
  5. crl.isRevoked(certificate);

11#SSL,构建KeyManagerFactory

  1. KeyManagerFactory factory =KeyManagerFactory.getInstance("SunX509");
  2. FileInputStream is = new FileInputStream("/Users/caishuzhan/Desktop/workspace/Awards/app/YHGJ.jks");
  3. KeyStore keyStore = KeyStore.getInstance("jks");
  4. keyStore.load(is,"123456".toCharArray());
  5. is.close();
  6. factory.init(keyStore,"123456".toCharArray());

构建信任工厂

  1. TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509");
  2. FileInputStream is = new FileInputStream("/Users/caishuzhan/Desktop/workspace/Awards/app/YHGJ.jks");
  3. KeyStore keyStore = KeyStore.getInstance("jks");
  4. keyStore.load(is,"123456".toCharArray());
  5. is.close();
  6. factory.init(keyStore);

构建SSLSocketFactory

  1. public static KeyStore getKeyStore(String path,String password){
  2. KeyStore keyStore = null;
  3. try {
  4. FileInputStream is = new FileInputStream(path);
  5. keyStore = KeyStore.getInstance("jks");
  6. keyStore.load(is,password.toCharArray());
  7. is.close();
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. return keyStore;
  12. }
  13. public static SSLSocketFactory getSSLSocketFactory(String password, String keyStorePath,String trustKeyStorePath){
  14. try {
  15. KeyStore keyStore = getKeyStore(keyStorePath,password);
  16. KeyManagerFactory keyManagerFactory =KeyManagerFactory.getInstance("SunX509");
  17. keyManagerFactory.init(keyStore,password.toCharArray());
  18. KeyStore trustKeyStore = getKeyStore(trustKeyStorePath,password);
  19. TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
  20. trustManagerFactory.init(trustKeyStore);
  21. SSLContext ctx = SSLContext.getInstance("SSL");
  22. ctx.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(),null);
  23. SSLSocketFactory sf = ctx.getSocketFactory();
  24. return sf;
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. return null;
  29. }

与服务端建立SSLSocket连接并且获取证书链

  1. public Certificate[] getCertificates(){
  2. try {
  3. SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
  4. SSLSocket sslSocket = (SSLSocket) factory.createSocket();
  5. sslSocket.startHandshake();
  6. SSLSession session = sslSocket.getSession();
  7. sslSocket.close();
  8. return session.getPeerCertificates();
  9. } catch (Exception e) {
  10. System.out.println("e :"+ e.getMessage());
  11. e.printStackTrace();
  12. }
  13. return null;
  14. }

12#Base64算法,约为原文的4/3倍,字符数以4为单位的整数倍,java.util的基本实现

  1. byte[] encode = Base64.getEncoder().encode("caishuzhan".getBytes());
  2. byte[] decode = Base64.getDecoder().decode(encode);

13#几种对称加密所支持的规格

1.png
2.png
3.png
4.png
5.png
1.png

RSA签名算法

1.png

DSA签名算法

1.png

ECDSA签名算法

1.png

PBE是一种基于口令和盐的对称加密算法,在初始化盐时,必须采用随机的方式SecureRandom构建,最终产生一个8个字节的字节数组,加解密如下

  1. //明文
  2. String data = "caishuzhan";
  3. //口令
  4. String password = "password";
  5. SecureRandom random = new SecureRandom();
  6. byte[] salt = random.generateSeed(8);
  7. PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
  8. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
  9. SecretKey secretKey = keyFactory.generateSecret(keySpec);
  10. PBEParameterSpec parameterSpec = new PBEParameterSpec(salt,100);
  11. Cipher cipher =Cipher.getInstance("PBEWithMD5AndDES");
  12. cipher.init(Cipher.ENCRYPT_MODE,secretKey,parameterSpec);
  13. byte[] doFinal = cipher.doFinal(data.getBytes());
  14. cipher.init(Cipher.DECRYPT_MODE,secretKey,parameterSpec);
  15. byte[] result = cipher.doFinal(doFinal);

#14有关HTTPS的数字证书验证流程

1.png

第一阶段为商榷算法

1)客户端产生随机数RNC,这个随机数为后续构建密钥做准备
2)客户端将自身支持的SSL(版本和种类),算法信息和随机数RNC发送给服务器
3)服务器接收到以后产生随机数RNS,为后续构建密钥做准备
4)服务器将自身支持的SSL(版本和种类),算法信息和随机数RNS 和 服务器证书 甚至包含客户端证书的请求(双向认证时)回应给客户端
此时,确认双方交互时所使用的加密算法

第二阶段为验证证书

1)客户端将该证书发送至认证机构,认证机构验证证书
2)认证机构返回结果,认证失败时提示警告
此时,认证完毕,客户端和服务器可以进行以服务端单向认证为基础的加密交互,如果服务端对客户端的身份有要求会要求客户端提供证书(双向认证时),一般情况下客户端证书不是必需,双向认证是电子商务确保安全的必要环节

第三阶段为产生密钥

1)客户端产生随机数,做为预备密钥PMS
2)客户端用服务器证书中的公钥对PMS加密
3)客户端将PMS加密信息发送到服务器
4)服务器使用私钥对信息解密获得PMS
5)客户端使用RNCRNSPMS构建主密钥MS
6)服务器使用RNCRNSPMS构建主密钥MS
5,6不存在次序关系,实际上异步完成

第四阶段构建完成主密钥后,开始终止握手协议交互

image.png
如果上述一些列操作中任何一端受到干扰发生异常,则重新进入协商算法阶段

第五阶段为加密交互

image.png
所有握手交互的现实封装在SSL层

以上为所有内容!