📜  java中的密码加解密(1)

📅  最后修改于: 2023-12-03 15:16:32.454000             🧑  作者: Mango

Java中的密码加解密

在Java中处理敏感信息时,如密码,我们往往需要对其进行加解密来保障安全性。本文将介绍几种常见的Java密码加解密方式。

1. 使用Java Cryptography Extension (JCE)

JCE为Java提供了一套密码学扩展,包含多种加解密算法。以下是使用JCE进行AES对称加解密的示例代码:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Base64;

public class AesUtil {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    private static final String CHARSET_NAME = StandardCharsets.UTF_8.name();

    public static String encrypt(String key, String plainText) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] cipherByteArray = cipher.doFinal(plainText.getBytes(CHARSET_NAME));
        return new String(Base64.encodeBase64(cipherByteArray), CHARSET_NAME);
    }

    public static String decrypt(String key, String cipherText) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] cipherByteArray = Base64.decodeBase64(cipherText.getBytes(CHARSET_NAME));
        byte[] plainByteArray = cipher.doFinal(cipherByteArray);
        return new String(plainByteArray, CHARSET_NAME);
    }
}

示例代码中使用AES对称加解密算法,加密模式为ECB,填充方式为PKCS5Padding。使用时,只需调用AesUtil.encrypt(key, plainText)加密明文,调用AesUtil.decrypt(key, cipherText)解密密文。

2. 使用Bouncy Castle

Bouncy Castle是一个开源的Java密码学API,提供了丰富的密码加解密算法。以下是使用Bouncy Castle进行AES对称加解密的示例代码:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.nio.charset.StandardCharsets;
import java.security.Security;

public class AesUtil {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    private static final String CHARSET_NAME = StandardCharsets.UTF_8.name();

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static String encrypt(String key, String plainText) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION, "BC");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] cipherByteArray = cipher.doFinal(plainText.getBytes(CHARSET_NAME));
        return new String(Base64.encodeBase64(cipherByteArray), CHARSET_NAME);
    }

    public static String decrypt(String key, String cipherText) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_NAME), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION, "BC");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] cipherByteArray = Base64.decodeBase64(cipherText.getBytes(CHARSET_NAME));
        byte[] plainByteArray = cipher.doFinal(cipherByteArray);
        return new String(plainByteArray, CHARSET_NAME);
    }
}

使用时,只需调用AesUtil.encrypt(key, plainText)加密明文,调用AesUtil.decrypt(key, cipherText)解密密文。

3. 使用Java KeyStore

Java KeyStore是Java中管理密钥的重要工具,可以将密钥保存在文件中。以下是使用Java KeyStore进行AES对称加解密的示例代码:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class AesUtil {
    private static final String KEYSTORE_TYPE = "JCEKS";
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    private static final String CHARSET_NAME = StandardCharsets.UTF_8.name();

    public static void generateKeyStore(String keyStoreFile, String keyStorePassword, String keyAlias, String keyPassword) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
        keyStore.load(null, null);
        byte[] keyData = "1234567890abcdef".getBytes(CHARSET_NAME);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyData, ALGORITHM);
        Key key = new SecretKeySpec(keyData, ALGORITHM);
        KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKeySpec);
        KeyStore.PasswordProtection keyPasswordProtection = new KeyStore.PasswordProtection(keyPassword.toCharArray());
        keyStore.setEntry(keyAlias, secretKeyEntry, keyPasswordProtection);
        FileOutputStream fileOutputStream = new FileOutputStream(keyStoreFile);
        keyStore.store(fileOutputStream, keyStorePassword.toCharArray());
        fileOutputStream.close();
    }

    public static String encrypt(String keyStoreFile, String keyStorePassword, String keyAlias, String keyPassword, String plainText) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
        FileInputStream fileInputStream = new FileInputStream(keyStoreFile);
        keyStore.load(fileInputStream, keyStorePassword.toCharArray());
        Key key = keyStore.getKey(keyAlias, keyPassword.toCharArray());
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherByteArray = cipher.doFinal(plainText.getBytes(CHARSET_NAME));
        return new String(Base64.encodeBase64(cipherByteArray), CHARSET_NAME);
    }

    public static String decrypt(String keyStoreFile, String keyStorePassword, String keyAlias, String keyPassword, String cipherText) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
        FileInputStream fileInputStream = new FileInputStream(keyStoreFile);
        keyStore.load(fileInputStream, keyStorePassword.toCharArray());
        Key key = keyStore.getKey(keyAlias, keyPassword.toCharArray());
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] cipherByteArray = Base64.decodeBase64(cipherText.getBytes(CHARSET_NAME));
        byte[] plainByteArray = cipher.doFinal(cipherByteArray);
        return new String(plainByteArray, CHARSET_NAME);
    }
}

使用时,先调用AesUtil.generateKeyStore(keyStoreFile, keyStorePassword, keyAlias, keyPassword)生成密钥库文件,然后调用AesUtil.encrypt(keyStoreFile, keyStorePassword, keyAlias, keyPassword, plainText)加密明文,调用AesUtil.decrypt(keyStoreFile, keyStorePassword, keyAlias, keyPassword, cipherText)解密密文。

总结

本文介绍了三种常见的Java密码加解密方式:JCE、Bouncy Castle和Java KeyStore,分别适用于不同的场景。使用时,需要考虑加解密算法的安全性和性能等因素,选择合适的方式进行加解密。