欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java加密实现

程序员文章站 2024-01-16 20:53:58
...

要实现加解密,最简单实现如下:
核心类Ciper,三步走:(以"RSA"为例)
1.获取Keypair(公钥私钥对)。生成或者获取公钥和私钥。
生成Keypair过程,可以写死到文件里,去读取。或者通过api自动生成。
2.实例化Cipher,约定算法
2.初始化Cipher,定义是加密还是解密。是公约加密啊,还是私钥加密,是公钥解密,还是私钥解密。
3.获取加密或解密的结果。

// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
// 初始化**对生成器,**大小为96-1024位  
keyPairGen.initialize(1024,new SecureRandom());  
// 生成一个**对,保存在keyPair中  
KeyPair keyPair = keyPairGen.generateKeyPair();  
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  

//**公钥加密**
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher. ENCRYPT_MODE, publicKey);
cipher.doFinal(minwen.getBytes("UTF-8")
//**私钥解密**
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
cipher.doFinal(miwen.getBytes("UTF-8")

补充:

a) 由于多平台加解密会存在不兼容的问题。(如:Android系统和windows,linux平台默认支持的加密算法不一致)Ciper实例化,需要使用第三方类 BouncyCastleProvider 代码如下:

Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding",
                new BouncyCastleProvider().getName());
//算法类型/工作方式/填充方式

b) 为了让字节数组转字符串格式固定,一般需要用到base64转码
apache.commons-codex下的base64类

    //base64 解码
    public static String decode(byte[] bytes) {  
        return new String(Base64.decodeBase64(bytes));  
    }  
  
    //base64 编码
    public static String encode(byte[] bytes) {  
        return new String(Base64.encodeBase64(bytes));  
    }  

c) 如果要打印出公钥,私钥,可通过 java.security.Key获取字节,再转字符串。

/**
     * Returns the key in its primary encoding format, or null
     * if this key does not support encoding.
     *
     * @return the encoded key, or null if the key does not support
     * encoding.
     */
    public byte[] getEncoded();

d) 若有需要在加解密中加入自己的算法逻辑,如字节数组重排等,可见Ciper类其他api。

 /**
     * Finishes a multi-part transformation (encryption or decryption).
     * <p>
     * Processes any bytes that may have been buffered in previous {@code
     * update} calls.
     * <p>
     * The final transformed bytes are stored in the {@code output} buffer.
     *
     * @param output
     *            the output buffer.
     * @param outputOffset
     *            the offset in the output buffer.
     * @return the number of bytes placed in the output buffer.
     * @throws IllegalBlockSizeException
     *             if the size of the resulting bytes is not a multiple of the
     *             cipher block size.
     * @throws ShortBufferException
     *             if the size of the {@code output} buffer is too small.
     * @throws BadPaddingException
     *             if the padding of the data does not match the padding scheme.
     * @throws IllegalStateException
     *             if this cipher instance is not initialized for encryption or
     *             decryption.
     */
    public final int doFinal(byte[] output, int outputOffset)
            throws IllegalBlockSizeException, ShortBufferException,
            BadPaddingException {
        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
            throw new IllegalStateException();
        }
        if (outputOffset < 0) {
            throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset);
        }
        return getSpi().engineDoFinal(null, 0, 0, output, outputOffset);
    }
 /**
     * Finishes a multi-part transformation (encryption or decryption).
     * <p>
     * Processes the bytes in {@code input} buffer, and any bytes that have been
     * buffered in previous {@code update} calls.
     *
     * @param input
     *            the input buffer.
     * @return the final bytes from the transformation.
     * @throws IllegalBlockSizeException
     *             if the size of the resulting bytes is not a multiple of the
     *             cipher block size.
     * @throws BadPaddingException
     *             if the padding of the data does not match the padding scheme.
     * @throws IllegalStateException
     *             if this cipher instance is not initialized for encryption or
     *             decryption.
     */
    public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException,
            BadPaddingException {
        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
            throw new IllegalStateException();
        }
        return getSpi().engineDoFinal(input, 0, input.length);
    }
 /**
     * Finishes a multi-part transformation (encryption or decryption).
     * <p>
     * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
     * inputOffset}, and any bytes that have been buffered in previous {@code
     * update} calls.
     *
     * @param input
     *            the input buffer.
     * @param inputOffset
     *            the offset in the input buffer.
     * @param inputLen
     *            the length of the input
     * @return the final bytes from the transformation.
     * @throws IllegalBlockSizeException
     *             if the size of the resulting bytes is not a multiple of the
     *             cipher block size.
     * @throws BadPaddingException
     *             if the padding of the data does not match the padding scheme.
     * @throws IllegalStateException
     *             if this cipher instance is not initialized for encryption or
     *             decryption.
     * @throws IllegalArgumentException
     *             if {@code inputOffset} and {@code inputLen} do not specify an
     *             valid chunk in the input buffer.
     */
    public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
            throws IllegalBlockSizeException, BadPaddingException {
        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
            throw new IllegalStateException();
        }
        checkInputOffsetAndCount(input.length, inputOffset, inputLen);
        return getSpi().engineDoFinal(input, inputOffset, inputLen);
    }

 /**
     * Finishes a multi-part transformation (encryption or decryption).
     * <p>
     * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
     * inputOffset}, and any bytes that have been buffered in previous {@code
     * update} calls.
     *
     * @param input
     *            the input buffer.
     * @param inputOffset
     *            the offset in the input buffer.
     * @param inputLen
     *            the length of the input.
     * @param output
     *            the output buffer for the transformed bytes.
     * @param outputOffset
     *            the offset in the output buffer.
     * @return the number of bytes placed in the output buffer.
     * @throws ShortBufferException
     *             if the size of the {@code output} buffer is too small.
     * @throws IllegalBlockSizeException
     *             if the size of the resulting bytes is not a multiple of the
     *             cipher block size.
     * @throws BadPaddingException
     *             if the padding of the data does not match the padding scheme.
     * @throws IllegalStateException
     *             if this cipher instance is not initialized for encryption or
     *             decryption.
     * @throws IllegalArgumentException
     *             if {@code inputOffset} and {@code inputLen} do not specify an
     *             valid chunk in the input buffer.
     */
  public final int doFinal(byte[] input, int inputOffset, int inputLen,
            byte[] output, int outputOffset) throws ShortBufferException,
            IllegalBlockSizeException, BadPaddingException {
        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
            throw new IllegalStateException();
        }
        checkInputOffsetAndCount(input.length, inputOffset, inputLen);
        return getSpi().engineDoFinal(input, inputOffset, inputLen, output,
                outputOffset);
    }
  /**
     * Continues a multi-part transformation (encryption or decryption). The
     * transformed bytes are returned.
     *
     * @param input
     *            the input bytes to transform.
     * @return the transformed bytes in a new buffer, or {@code null} if the
     *         input has zero length.
     * @throws IllegalStateException
     *             if this cipher instance is not initialized for encryption or
     *             decryption.
     * @throws IllegalArgumentException
     *             if the input is {@code null}.
     */
    public final byte[] update(byte[] input) {
        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
            throw new IllegalStateException();
        }
        if (input == null) {
            throw new IllegalArgumentException("input == null");
        }
        if (input.length == 0) {
            return null;
        }
        return getSpi().engineUpdate(input, 0, input.length);
    }

更多实现可参考:
https://www.cnblogs.com/lz2017/p/6917049.html