org.javaweb.utils.RSAUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.javaweb.utils.RSAUtils.java

Source

/*
 * Copyright yz 2017-11-23 Email:admin@javaweb.org.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.javaweb.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA
 */
public class RSAUtils {

    /**
     * ??
     */
    private static final String ALGORITHM = "RSA/None/NoPadding";

    /**
     * RSA??,java.security.Signature???
     */
    private static final String SIGNATURE_ALGORITHM = "SHA512withRSA";

    /**
     * ?
     *
     * @return
     */
    private static Cipher getCipher() {
        try {
            return Cipher.getInstance(ALGORITHM);
        } catch (Exception e) {
            try {
                return Cipher.getInstance("RSA");
            } catch (Exception ex) {
                return null;
            }
        }
    }

    /**
     * RSA
     *
     * @param encrypted 
     * @param key       ?
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] encrypted, Key key) throws Exception {
        Cipher cipher = getCipher();
        cipher.init(Cipher.ENCRYPT_MODE, key);

        return segmentEncrypt(encrypted, cipher, Cipher.ENCRYPT_MODE, ((RSAKey) key).getModulus().bitLength());
    }

    /**
     * RSA
     *
     * @param encrypted 
     * @param key       ?
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] encrypted, Key key) throws Exception {
        Cipher cipher = getCipher();
        cipher.init(Cipher.DECRYPT_MODE, key);

        return segmentEncrypt(encrypted, cipher, Cipher.DECRYPT_MODE, ((RSAKey) key).getModulus().bitLength());
    }

    /**
     * RSA
     *
     * @param data
     * @param cipher
     * @param mode
     * @param keySize
     * @return
     * @throws Exception
     */
    private static byte[] segmentEncrypt(byte[] data, Cipher cipher, int mode, int keySize) throws Exception {
        int maxBlock = 0;

        if (mode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }

        int offSet = 0;
        int index = 0;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        while (data.length > offSet) {
            if (data.length - offSet > maxBlock) {
                out.write(cipher.doFinal(data, offSet, maxBlock));
            } else {
                out.write(cipher.doFinal(data, offSet, data.length - offSet));
            }

            offSet = ++index * maxBlock;
        }

        return out.toByteArray();
    }

    /**
     * 
     *
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        return keyFactory.generatePublic(spec);
    }

    /**
     * ?
     *
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        return keyFactory.generatePrivate(spec);
    }

    /**
     * ?RSA?
     *
     * @param keySize
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair generateKey(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = new SecureRandom();
        keygen.initialize(keySize, random);

        return keygen.generateKeyPair();
    }

    /**
     * RSA???
     *
     * @param data ?
     * @param key  ?
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, Key key) throws Exception {
        byte[] keyBytes = key.getEncoded();
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

        signature.initSign(privateK);
        signature.update(data);

        return Base64.encodeBase64String(signature.sign());
    }

    /**
     * RSA???
     *
     * @param data ?
     * @param key  
     * @param sign ??Base64
     * @return
     * @throws Exception
     */
    public static boolean verify(byte[] data, Key key, String sign) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);

        return signature.verify(Base64.decodeBase64(sign));
    }

    /**
     * ??RSA Key
     *
     * @param key
     * @return
     */
    public static String formatStandardPublicKey(String key) {
        return formatStandardKey(key, "PUBLIC");
    }

    /**
     * ??RSA Key?
     *
     * @param key
     * @return
     */
    public static String formatStandardPrivate(String key) {
        return formatStandardKey(key, "RSA PRIVATE");
    }

    /**
     * ??RSA Key
     *
     * @param key
     * @return
     */
    private static String formatStandardKey(String key, String type) {
        char[] chars = key.toCharArray();
        StringBuilder sb = new StringBuilder("-----BEGIN " + type + " KEY-----");

        for (int i = 0; i < chars.length; i++) {
            char chr = chars[i];

            if (i % 64 == 0) {
                sb.append("\n");
            }

            sb.append(chr);
        }

        sb.append("\n-----END " + type + " KEY-----");

        return sb.toString();
    }

    /**
     * ?RSA Key??Java?Key
     *
     * @param key
     * @return
     */
    public static String formatJavaKey(String key) {
        return key.replaceAll("\\s*-+.*?-+\\s*", "").replaceAll("\\s+", "");
    }

}