Java加解密服务API解读

引言

本文是对Java Crypto API的解读 。Java Cryptography API允许你对数据进行加解密操作,同时进行秘钥管理,签名等操作。

Java加解密服务涉及的包有:

  1. java.security
  2. java.security.cert
  3. java.security.spec
  4. java.security.interfaces
  5. javax.crypto
  6. javax.crypto.spec
  7. javax.crypto.interfaces

核心类为:

  1. Provider
  2. SecureRandom
  3. Cipher
  4. MessageDigest
  5. Signature
  6. Mac
  7. AlgorithmParameters
  8. AlgorithmParameterGenerator
  9. KeyFactory
  10. SecretKeyFactory
  11. KeyPairGenerator
  12. KeyGenerator
  13. KeyAgreement
  14. KeyStore
  15. CertificateFactory
  16. CertPathBuilder
  17. CertPathValidator
  18. CertStore

Provider

java.security.Provider是指Java算法提供商,要使用Java Crypto API,你必须提供一个Provider,JDK拥有自己的实现,如果你未提供Provider,默认使用JDK提供的Provider.目前,最流行的ProviderBouncyCastleProvider

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;

public class ProviderExample {
    public static void main(String[] args) {
        Security.addProvider(new BouncyCastleProvider());
    }
}

Cipher
javax.crypto.Cipher代表一种加解密算法,Cipher用来对数据进行加解密操作。

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

在使用Cipher之前,必须通过调用init()进行初始化操作,该方法传递两个参数:

  1. Encryption / Decryption cipher mode 加密或是解密模式
  2. Key 加解密秘钥
byte[] keyBytes   = new byte[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
String algorithm  = "RawBytes";
SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm);

cipher.init(Cipher.ENCRYPT_MODE, key);

请注意,出于安全考虑,我们通常不会在实际生产过程中所使用上述方法进行加解密,而是使用数字证书进行秘钥管理。

一旦调用init()方法成功,我们就可以调用update()或是doFinal()方法对数据进行加解密操作,以上方法都需要传递要加解密的数据。

byte[] plainText  = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8");
byte[] cipherText = cipher.doFinal(plainText);

Keys

对数据进行加解密,你需要Keys,目前有两种类型的Keys:

  1. Symmetric keys 对称密钥
  2. Asymmetric keys 非对称密钥

Keys的选取,取决于你所使用的加解密算法(对称加密和非对称加密),对称加密使用同一个Key进行数据的加密和解密;与之相反,非对称加密使用不同的Key进行加密和解密,具体点说就是使用私钥(Private Key)进行加密,使用(Public Key)进行解密。

以下是秘钥的生成:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

SecureRandom secureRandom = new SecureRandom();
int keyBitSize = 256;
keyGenerator.init(keyBitSize, secureRandom);

SecretKey secretKey = keyGenerator.generateKey();

上述代码生成的SecretKey可以传递到 Cipher.init()方法:

cipher.init(Cipher.ENCRYPT_MODE, secretKey);

非对称加密需要不同的Key,分别用来加解密:

SecureRandom secureRandom = new SecureRandom();

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");

KeyPair keyPair = keyPairGenerator.generateKeyPair();

KeyStore

The Java KeyStore is a database that can contain keys
KeyStore可以管理以下信息:

  1. Private keys
  2. Public keys + certificates
  3. Secret keys

公钥和私钥用于非对称加密,一个公钥可以与一个证书进行关联。
秘钥用于对称加密。

A certificate is a document that verifies the identity of the person, organization or device claiming to own the public key. A certificate is typically digitally signed by the verifying party as proof.


Keytool

The Java Keytool is a command line tool that can work with Java KeyStore files. The Keytool can generate key pairs into a KeyStore file, export certificates from, and import certificates into a KeyStore and several other functions.


MessageDigest

A message digest is a hash value calculated from the message data. If a byte is changed in the encrypted data, the message digest calculated from the data will change too.
当你接收到别人发送的一段加密后的数据,你如何得知,是否被其他人修改过呢?
一个常见的解决方案是在数据加密发送前,计算message digest,然后将本来的数据和message digest一起加密发送给他人。

当接收方接收到加密数据,对其解密,并计算message digest与发送方发送的message digest进行比较,如果两者相同,说明传递消息并未被修改。

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");

byte[] data1 = "0123456789".getBytes("UTF-8");

byte[] digest = messageDigest.digest(data1);

Mac

he term MAC is short for Message Authentication Code. A MAC is similar to a message digest, but uses an additional key to encrypt the message digest. Only by having both the original data and the key can you verify the MAC.

Mac mac = Mac.getInstance("HmacSHA256");

byte[] keyBytes   = new byte[]{0,1,2,3,4,5,6,7,8 ,9,10,11,12,13,14,15};
String algorithm  = "RawBytes";
SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm);

mac.init(key);


byte[] data = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");

byte[] macBytes = mac.doFinal(data);

Signature 数字签名

A digital signature is created by creating a message digest (hash) from the data, and encrypting that message digest with the private key of the device, person or organization that is to sign the data. The encrypted message digest is called a digital signature.

Signature signature = Signature.getInstance("SHA256WithDSA");

signature.initSign(keyPair.getPrivate(), secureRandom);


byte[] data = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
signature.update(data);

byte[] digitalSignature = signature.sign();

Verifying a Signature数字验签

Signature signature = Signature.getInstance("SHA256WithDSA");

signature.initVerify(keyPair.getPublic());



byte[] data2 = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
signature2.update(data2);

boolean verified = signature2.verify(digitalSignature);

未完待续...

参考链接:http://tutorials.jenkov.com/java-cryptography/index.html

原文地址:https://www.cnblogs.com/claindoc/p/9841945.html