Java tutorial
/* * 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+", ""); } }