zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Linux 磁盘挂载和mount共享
    Socket编程实践(8) --Select-I/O复用
    JavaScript 作用域链图具体解释
    扩展MongoDB C# Driver的QueryBuilder
    Gray Code
    Android网络编程Socket【实例解析】
    设计模式之:代理模式
    LOL英雄联盟代打外挂程序-java实现
    MySQL系列:innodb源代码分析之线程并发同步机制
    linux压缩打包
  • 原文地址:https://www.cnblogs.com/claindoc/p/9841945.html
Copyright © 2011-2022 走看看