1. 程式人生 > >Java加解密服務API解讀

Java加解密服務API解讀

ase dsa secret ner adding ogr 傳遞 ast 秘鑰

引言

本文是對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.目前,最流行的Provider

BouncyCastleProvider

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

Java加解密服務API解讀