Java tutorial
// ---------------------------------------------------------------------------- // Copyright (C) Yukar 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.yukar.framework.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.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; 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.yukar.framework.lang.StandardRuntimeException; /** * * <dl> * <dt>? * <dd>?????? * </dl> * @author nilcy */ public final class SecurityHelper { /** */ 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.getInstanceStrong(); } /** * RSA??? * <dl> * <dt>? * <dd>RSA??????2048?????? * </dl> * @return RSA? */ public static KeyPair createKeyPair() { try { final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); 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("RSA"); 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("RSA"); 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("RSA/ECB/PKCS1Padding"); 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("RSA/ECB/PKCS1Padding"); 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("AES/CBC/PKCS5Padding"); 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("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv); return cipher.doFinal(input); } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) { throw new StandardRuntimeException(e); } } /** * ????? * <dl> * <dt>? * <dd>EC??????256?????? * </dl> * @return ?(???) */ public static KeyPair createSignKeyPair() { try { final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); keyPairGenerator.initialize(256); return keyPairGenerator.generateKeyPair(); } catch (final NoSuchAlgorithmException e) { throw new RuntimeException(e); } } /** * ???? * <dl> * <dt>? * <dd>NONEwithECDSA??????????????? * </dl> * @param key ? * @param data * @return ?? */ public static byte[] sign(final PrivateKey key, final byte[] data) { try { final Signature sign = Signature.getInstance("NONEwithECDSA"); sign.initSign(key); sign.update(data); return sign.sign(); } catch (final NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { throw new StandardRuntimeException(e); } } /** * ??? * <dl> * <dt>? * <dd>NONEwithECDSA?????????????? * </dl> * @param publicKey ? * @param message * @param signature ?? * @return ? */ public static boolean verify(final PublicKey publicKey, final byte[] signature, final byte[] message) { try { final Signature sign = Signature.getInstance("NONEwithECDSA"); sign.initVerify(publicKey); sign.update(message); return sign.verify(signature); } catch (final NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { throw new StandardRuntimeException(e); } } }