Java tutorial
// ---------------------------------------------------------------------------- // Copyright (C) Aynu Evolution Laboratory. All rights reserved. // GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 // http://www.gnu.org/licenses/gpl-3.0-standalone.html // ---------------------------------------------------------------------------- package com.github.aynu.mosir.core.standard.util; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.aynu.mosir.core.standard.lang.StandardRuntimeException; /** * * <dl> * <dt>? * <dd>?????? * </dl> * @author nilcy */ public final class SecurityHelper { /** ? */ private static final String ALGO_KEY = "RSA"; /** ?(??) */ private static final String ALGO_CIPHER_SMALL = "RSA/ECB/PKCS1Padding"; /** ?(?) */ private static final String ALGO_CIPHER_BIG = "AES/CBC/PKCS5Padding"; /** */ private static final Logger LOG = LoggerFactory.getLogger(SecurityHelper.class); /** ? */ private SecurityHelper() { } /** * ??? * <dl> * <dt>? * <dd>?????????? * </dl> * @return ?? * @throws NoSuchAlgorithmException ?? */ public static SecureRandom getSecureRandom() throws NoSuchAlgorithmException { return SecureRandom.getInstance("SHA1PRNG"); // return SecureRandom.getInstanceStrong(); } /** * RSA??? * <dl> * <dt>? * <dd>RSA??????2048?????? * </dl> * @return RSA? */ public static KeyPair createKeyPair() { try { final KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGO_KEY); generator.initialize(2048); final KeyPair pair = generator.generateKeyPair(); if (LOG.isDebugEnabled()) { final RSAPublicKey publicKey = (RSAPublicKey) pair.getPublic(); final RSAPrivateKey privateKey = (RSAPrivateKey) pair.getPrivate(); LOG.debug("public-modulus={}", Base64.encodeBase64String(publicKey.getModulus().toByteArray())); LOG.debug("public-exponent={}", Base64.encodeBase64String(publicKey.getPublicExponent().toByteArray())); LOG.debug("private-modulus={}", Base64.encodeBase64String(privateKey.getModulus().toByteArray())); LOG.debug("private-exponent={}", Base64.encodeBase64String(privateKey.getPrivateExponent().toByteArray())); } return pair; } catch (final NoSuchAlgorithmException e) { throw new StandardRuntimeException(e); } } /** * RSA??? * <dl> * <dt>? * <dd>RSA????????????? * </dl> * @param modulus * @param exponent ?? * @return RSA? */ public static RSAPublicKey createPublicKey(final BigInteger modulus, final BigInteger exponent) { try { final KeyFactory keyFactory = KeyFactory.getInstance(ALGO_KEY); return (RSAPublicKey) keyFactory.generatePublic(new RSAPublicKeySpec(modulus, exponent)); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new StandardRuntimeException(e); } } /** * RSA??? * <dl> * <dt>? * <dd>RSA????????????? * </dl> * @param modulus * @param exponent ?? * @return RSA? */ public static RSAPrivateKey createPrivateKey(final BigInteger modulus, final BigInteger exponent) { try { final KeyFactory keyFactory = KeyFactory.getInstance(ALGO_KEY); return (RSAPrivateKey) keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, exponent)); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new StandardRuntimeException(e); } } /** * ??? * <dl> * <dt>? * <dd>PBKDF2WithHmacSHA1?????????65536?128?????? * </dl> * @param password * @param salt * @return ? */ public static SecretKey createSecretKey(final char[] password, final byte[] salt) { try { final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); final KeySpec spec = new PBEKeySpec(password, salt, 65536, 128); return factory.generateSecret(spec); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new StandardRuntimeException(e); } } /** * AES??? * <dl> * <dt>? * <dd>AES?????? * </dl> * @param key ? * @return AES? */ public static SecretKey createSecretKey(final byte[] key) { return new SecretKeySpec(key, "AES"); } /** * ???? * <dl> * <dt>? * <dd>RSA/ECB/PKCS1Padding??????? * </dl> * @param key ? * @param input * @return ? */ public static byte[] encrypt(final Key key, final byte[] input) { try { final Cipher cipher = Cipher.getInstance(ALGO_CIPHER_SMALL); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(input); } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { throw new StandardRuntimeException(e); } } /** * ???? * <dl> * <dt>? * <dd>RSA/ECB/PKCS1Padding??????? * </dl> * @param key ? * @param input * @return ? */ public static byte[] decrypt(final Key key, final byte[] input) { try { final Cipher cipher = Cipher.getInstance(ALGO_CIPHER_SMALL); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(input); } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { throw new StandardRuntimeException(e); } } /** * ??? * <dl> * <dt>? * <dd>AES/CBC/PKCS5Padding??????? * </dl> * @param key ? * @param iv ? * @param input * @return ? */ public static byte[] encrypt(final Key key, final IvParameterSpec iv, final byte[] input) { try { final Cipher cipher = Cipher.getInstance(ALGO_CIPHER_BIG); cipher.init(Cipher.ENCRYPT_MODE, key, iv); return cipher.doFinal(input); } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) { throw new StandardRuntimeException(e); } } /** * ??? * <dl> * <dt>? * <dd>AES/CBC/PKCS5Padding??????? * </dl> * @param key ? * @param iv ? * @param input * @return ? */ public static byte[] decrypt(final Key key, final IvParameterSpec iv, final byte[] input) { try { final Cipher cipher = Cipher.getInstance(ALGO_CIPHER_BIG); cipher.init(Cipher.DECRYPT_MODE, key, iv); return cipher.doFinal(input); } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) { throw new StandardRuntimeException(e); } } }