Java密码安全框架

Java密码

参考 Java加解密艺术这本书进行整理如下

对称加密 symmetric

  • AesCbcUtils
package com.security.symmetric;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * aes cbc and iv demo.
 * @author fitz
 * @version  1.0.0
 */
public class AesCbcUtils {

    // aes cipher mode
    public static final String CIPHER_ALGORITHM = "AES/CBC/NoPadding";

    // public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * encrypt
     * @param plain 16B
     * @param key 16B
     * @param iv 16B
     * @return byte[] 16B
     * @throws Exception
     */
    public static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception {
        if (key == null || key.length != 16 || iv == null || iv.length != 16) {
            throw new Exception("key or iv error");
        }
        SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivParameterSpec);
        byte[] encrypted = cipher.doFinal(plain);
        return encrypted;
    }

    /**
     * decrypt
     * @param crypt 16B
     * @param key 16B
     * @param iv 16B
     * @return byte[] 16B
     * @throws Exception
     */
    public static byte[] decrypt(byte[] crypt, byte[] key, byte[] iv) throws Exception {
        if (key == null || key.length != 16 || iv == null || iv.length != 16) {
            throw new Exception("key or iv error");
        }
        SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
        sKeySpec.getClass().getSimpleName();
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, ivParameterSpec);
        byte[] original = cipher.doFinal(crypt);
        return original;
    }

}

  • AesUtils
package com.security.symmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public class AesUtils {
    private static final String KEY_TYPE = "AES";
    private static final String CIPER_MODE = "AES/ECB/PKCS5PADDING";

    private static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_TYPE);
        return keyGenerator.generateKey();
    }

    private static byte[] encrypt(SecretKey key, byte[] data) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(key, data, CIPER_MODE);
    }

    private static byte[] decrypt(SecretKey key, byte[] cipherText) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(key, cipherText, CIPER_MODE);
    }

}

  • CipherAsymmetricUtils
package com.security.symmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public abstract class CipherAsymmetricUtils {
    public enum KeyTypeEnum {
        AES("AES"), DES("DES"), DESede("DESede"), IDEA("IDEA");
        private String keyType;
        private KeyTypeEnum(String keyType) {
            this.keyType = keyType;
        }
    }

    public enum WorkTypeEnum {
        ECB("ECB"), CBC("CBC");
        private String workType;
        private WorkTypeEnum(String workType) {
            this.workType = workType;
        }
    }

    public enum PaddingTypeEnum {
        NOPadding("NOPadding"), PKCS5Padding("PKCS5Padding"), PKCS7Padding("PKCS7Padding");
        private String paddingType;
        private PaddingTypeEnum(String paddingType) {
            this.paddingType = paddingType;
        }
    }

    public static byte[] encrypt(Key key, byte[] data, String cipherType) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(cipherType);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(Key key, byte[] cipherText, String cipherType) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(cipherType);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    public static SecretKey generateSecretKey(String keyType) throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(keyType);
        return keyGenerator.generateKey();
    }
}

  • Des3Utils
package com.security.symmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public class Des3Utils {
    private static final String KEY_TYPE = "DESede";
    private static final String CIPER_MODE = "DESede/ECB/PKCS5PADDING";

    private static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_TYPE);
        return keyGenerator.generateKey();
    }

    private static byte[] encrypt(SecretKey key, byte[] data) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(key, data, CIPER_MODE);
    }

    private static byte[] decrypt(SecretKey key, byte[] cipherText) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(key, cipherText, CIPER_MODE);
    }
}

  • DesUtils
package com.security.symmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public class DesUtils {
    private static final String KEY_TYPE = "DES";
    private static final String CIPER_MODE = "DES/ECB/PKCS5PADDING";

    private static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_TYPE);
        return keyGenerator.generateKey();
    }

    private static byte[] encrypt(SecretKey key, byte[] data) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(key, data, CIPER_MODE);
    }

    private static byte[] decrypt(SecretKey key, byte[] cipherText) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(key, cipherText, CIPER_MODE);
    }
}

  • CCM

  • IdeaUtils

package com.security.symmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public class IdeaUtils {
    private static final String KEY_TYPE = "IDEA";
    private static final String CIPER_MODE = "IDEA/ECB/PKCS5PADDING";

    private static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_TYPE);
        return keyGenerator.generateKey();
    }

    private static byte[] encrypt(SecretKey key, byte[] data) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(key, data, CIPER_MODE);
    }

    private static byte[] decrypt(SecretKey key, byte[] cipherText) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(key, cipherText, CIPER_MODE);
    }
}

  • PbeUtils
package com.security.symmetric;

import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

/**
 * @author fitz
 * @version 1.0
 */
public class PbeUtils {
    /**
     * 
     * PBEWithMD5AndDES
     * PBEWithMD5AndTripleDES
     * PBEWithSHA1AndDESede
     * PBEWithSHA1AndRC2_40
     * 
*/ private static final String ALGORITHM = "PBEWithMD5AndTripleDES"; private static final int ITERATION_COUNT = 100; public static SecretKey generateSecrectKey(String passwd) throws NoSuchAlgorithmException, InvalidKeySpecException { PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray()); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM); return secretKeyFactory.generateSecret(pbeKeySpec); } public static byte[] generateSalt() { SecureRandom random = new SecureRandom(); return random.generateSeed(8); } public static byte[] encrypt(SecretKey key, byte[] data, byte[] salt) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHM); PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, ITERATION_COUNT); cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec); return cipher.doFinal(data); } public static byte[] decrypt(SecretKey key, byte[] cipherText, byte[] salt) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHM); PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, ITERATION_COUNT); cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec); return cipher.doFinal(cipherText); } }
  • SecretKeyUtils
package com.security.symmetric;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

/**
 * @author fitz
 * @version 1.0
 */
public class SecretKeyUtils {
    public SecretKey getSecretKey(byte[] keyBytes, String keyType) {
        SecretKey secretKey = new SecretKeySpec(keyBytes, keyType);
        return secretKey;
    }

    public SecretKey generateSecretKey(String keyType, KeySpec keySpec) throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(keyType);
        return secretKeyFactory.generateSecret(keySpec);
    }
}

非对称加密

  • CipherAsymmetricUtils
package com.security.asymmetric;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public abstract class CipherAsymmetricUtils {
    public enum KeyTypeEnum {
        RSA("RSA"), ECC("ECC");
        private String keyType;
        private KeyTypeEnum(String keyType) {
            this.keyType = keyType;
        }
    }

    public enum WorkTypeEnum {
        ECB("ECB"), CBC("CBC");
        private String workType;
        private WorkTypeEnum(String workType) {
            this.workType = workType;
        }
    }

    public enum PaddingTypeEnum {
        NOPadding("NoPadding"), PKCS5Padding("PKCS5Padding"), PKCS7Padding("PKCS7Padding");
        private String paddingType;
        private PaddingTypeEnum(String paddingType) {
            this.paddingType = paddingType;
        }
    }

    public static byte[] encrypt(Key key, byte[] data, String cipherType) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(cipherType);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(Key key, byte[] cipherText, String cipherType) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(cipherType);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

}

  • DhKeyAgreementUtils
package com.security.asymmetric;

import com.security.util.ByteUtils;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.KDF1BytesGenerator;
import org.bouncycastle.crypto.params.ISO18033KDFParameters;

import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;

/**
 * @author fitz
 * @version 1.0
 */
public class DhKeyAgreementUtils {

    public static final String KEY_AGREEMENT_ALGORITHM_DH = "DH";
    public static final String KEY_AGREEMENT_ALGORITHM_ECDH = "ECDH";
    public static final String SECRET_KEY_ALGORITHM = "AES";

    public SecretKey generateSecretKey(PublicKey publicKey, PrivateKey privateKey, String keyAgreementType) throws Exception {
        KeyAgreement ka = KeyAgreement.getInstance(keyAgreementType);
        ka.init(privateKey);
        ka.doPhase(publicKey, true);
        SecretKey key = ka.generateSecret(SECRET_KEY_ALGORITHM);
        return key;
    }

    public byte[] generateSessionKeyPki(PublicKey publicKey, PrivateKey privateKey) throws Exception {
        KeyAgreement ka = KeyAgreement.getInstance("ECDH");   //EcDhWithNistKdf256
        ka.init(privateKey);
        ka.doPhase(publicKey, true);
        byte[] secret = ka.generateSecret();
        KDF1BytesGenerator kdf1sha1 = new KDF1BytesGenerator(new SHA1Digest());
        kdf1sha1.init(new ISO18033KDFParameters(secret));
        byte[] key = new byte[16];
        kdf1sha1.generateBytes(key,0,key.length);
        return key;
    }

    public void generateDiffHellmanKeys(String keyType, int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyType);
        keyPairGenerator.initialize(keySize);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // A privateKey & publicKey
        PrivateKey privateKeyA = keyPair.getPrivate();
        PublicKey publicKeyA = keyPair.getPublic();

        // B privateKey & publicKey
        keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKeyB = keyPair.getPrivate();
        PublicKey publicKeyB = keyPair.getPublic();
    }
}

  • EccCipherUtils
package com.security.asymmetric;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;

/**
 * @author fitz
 * @version 1.0
 */
public class EccCipherUtils {
    private static final String CIPHER_ALGORITHM = "ECC/ECB/PKCS5Padding";

    public static byte[] encrypt(ECPublicKey publicKey, byte[] data, String cipherType) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(publicKey, data, cipherType);
    }

    public static byte[] decrypt(ECPrivateKey privateKey, byte[] cipherText, String cipherType) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(privateKey, cipherText, cipherType);
    }
}

  • EccKeyGenerateUtils
package com.security.asymmetric;

import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;

/**
 * @author fitz
 * @version 1.0
 */
public class EccKeyGenerateUtils {

    /**
     * generate keypair
     * @param keyType
     * @param size
     * @return KeyPair
     *         can use KeyPair's getPublic or getPrivate
     * @throws NoSuchAlgorithmException
     */
    public KeyPair generateKey(String keyType, int size) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyType);
        keyPairGenerator.initialize(size);
        return keyPairGenerator.generateKeyPair();
    }

    public PublicKey getPublicKey(String x, String y) throws Exception {
        ECPoint ecPoint = new ECPoint(new BigInteger(Hex.decode(x)), new BigInteger(Hex.decode(y)));
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC", "BC");
        parameters.init(new ECGenParameterSpec("secp256r1"));
        ECParameterSpec ecParameters = parameters.getParameterSpec(ECParameterSpec.class);
        return KeyFactory.getInstance ("EC").generatePublic(new ECPublicKeySpec(ecPoint, ecParameters));
    }

}

  • RsaBlockUtils
package com.security.asymmetric;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;

/**
 * no use, just for test block
 * @author fitz
 */
public class RsaBlockUtils {
    public static final String CIPHER_ALGORITHM = "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING";


    // for rsa 2048
    private static final int KEY_SIZE = 2048;
    private static final int BLOCK_SIZE = 245;
    private static final int OUTPUT_BLOCK_SIZE = 256;

    // for rsa 1024
    // private static final int KEY_SIZE = 1024;
    // private static final int BLOCK_SIZE = 117;
    // private static final int OUTPUT_BLOCK_SIZE = 128;

    /**
     * encryptByPublicKey
     * @param data
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, Key publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        int blocks = data.length / BLOCK_SIZE;
        int lastBlockSize = data.length % BLOCK_SIZE;
        byte[] encryptedData = new byte[(lastBlockSize == 0 ? blocks : blocks + 1) * OUTPUT_BLOCK_SIZE];
        for (int i = 0; i < blocks; i++) {
            cipher.doFinal(data, i * BLOCK_SIZE, BLOCK_SIZE, encryptedData, i * OUTPUT_BLOCK_SIZE);
        }
        if (lastBlockSize != 0) {
            cipher.doFinal(data, blocks * BLOCK_SIZE, lastBlockSize, encryptedData, blocks
                    * OUTPUT_BLOCK_SIZE);
        }
        return encryptedData;

    }

    /**
     * decryptByPrivateKey
     * @param decoded
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] decoded, Key privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        int blocks = decoded.length / OUTPUT_BLOCK_SIZE;
        ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(decoded.length);
        for (int i = 0; i < blocks; i++) {
            decodedStream.write(cipher.doFinal(decoded, i * OUTPUT_BLOCK_SIZE, OUTPUT_BLOCK_SIZE));
        }
        return decodedStream.toByteArray();
    }
}

  • RsaCipherUtils
package com.security.asymmetric;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.security.*;
import java.security.spec.*;

/**
 * @author fitz
 * @version 1.0
 */
public class RsaCipherUtils {
    private static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS5Padding";

    public static byte[] encrypt(PublicKey publicKey, byte[] data, String cipherType) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.encrypt(publicKey, data, cipherType);
    }

    public static byte[] decrypt(PrivateKey privateKey, byte[] cipherText, String cipherType) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return CipherAsymmetricUtils.decrypt(privateKey, cipherText, cipherType);
    }

    public static byte[] encryptOaep(byte[] data, PublicKey publicKey) throws NoSuchProviderException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidParameterSpecException {
        AlgorithmParameters algp = AlgorithmParameters.getInstance("OAEP", "BC");
        AlgorithmParameterSpec paramSpec = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
        algp.init(paramSpec);
        Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING");
        oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publicKey, algp);  //algp
        byte[] ct = oaepFromAlgo.doFinal(data);
        return ct;
    }

}

  • RsaKeyGenerateUtils
package com.security.asymmetric;

import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

/**
 * @author fitz
 * @version 1.0
 */
public class RsaKeyGenerateUtils {

    /**
     * generate keypair
     * @param keyType
     * @param size
     * @return KeyPair
     *         can use KeyPair's getPublic or getPrivate
     * @throws NoSuchAlgorithmException
     */
    public KeyPair generateKey(String keyType, int size) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyType);
        keyPairGenerator.initialize(size);
        return keyPairGenerator.generateKeyPair();
    }

    public static Key toPrivateKey(String type, byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(type);
        return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    }

    public static Key toPublicKey(String type, byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(type);
        return keyFactory.generatePublic(x509EncodedKeySpec);
    }

    /**
     * Generate public key according to modulus and public exponent java Cipher*
     * @param modulus modulus
     * @param exponent public exponent
     * @return
     */
    public static RSAPublicKey getPublicKey(String modulus, String exponent) {
        try {
            BigInteger b1 = new BigInteger(modulus, 16);
            BigInteger b2 = new BigInteger(exponent, 16);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Generate private key according to modulus and private exponent java
     * @param modulus modulus
     * @param exponent private exponent
     * @return
     */
    public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {
        try {
            BigInteger b1 = new BigInteger(modulus, 16);
            BigInteger b2 = new BigInteger(exponent, 16);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

  • EccParams
  • RsaParams
  • KdfUtils

签名

  • KeyUtils
package com.security.signature;

import java.security.*;

/**
 * @author fitz
 * @version 1.0
 */
public class KeyUtils {
    public static final String ALGORITHM = "DSA";

    /**
     * generate keypair
     * @param keyType
     * @param size
     * @return KeyPair
     *         can use KeyPair's getPublic or getPrivate
     * @throws NoSuchAlgorithmException
     */
    public KeyPair generateKey(String keyType, int size) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyType);
        keyPairGenerator.initialize(size);
        return keyPairGenerator.generateKeyPair();
    }
}

  • EcdsaUtils
package com.security.signature;

import java.security.*;

/**
 * @author fitz
 * @version 1.0
 */
public class EcdsaUtils {
    private static final String KEY_ALGORITHM = "ECDSA";
    /**
     * NONEwithECDSA
     * RIPEMD160withECDSA
     * SHA1withECDSA
     * SHA224withECDSA
     * SHA256withECDSA
     * SHA384withECDSA
     * SHA512withECDSA
     */
    private static final String SIGNATURE_ALGORITHM = "SHA512withECDSA";


    public static byte[] sign(PrivateKey privateKey, byte[] data) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return SignatureUtils.sign(privateKey, data, SIGNATURE_ALGORITHM);
    }

    public static boolean verify(PublicKey publicKey, byte[] data, byte[] sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return SignatureUtils.verify(publicKey, data, sign, SIGNATURE_ALGORITHM);
    }
}

  • RsaSignUtils
package com.security.signature;

import java.security.*;

/**
 * @author fitz
 * @version 1.0
 */
public class RsaSignUtils {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

    public static byte[] sign(PrivateKey privateKey, byte[] data) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return SignatureUtils.sign(privateKey, data, SIGNATURE_ALGORITHM);
    }

    public static boolean verify(PublicKey publicKey, byte[] data, byte[] sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return SignatureUtils.verify(publicKey, data, sign, SIGNATURE_ALGORITHM);
    }
}

  • SignatureUtils
package com.security.signature;

import java.security.*;

/**
 * @author fitz
 * @version 1.0
 */
public class SignatureUtils {
    public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

    public static byte[] sign(PrivateKey privateKey, byte[] data, String signatureType) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance(signatureType);
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }

    public static boolean verify(PublicKey publicKey, byte[] data, byte[] sign, String signatureType) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance(signatureType);
        signature.initVerify(publicKey);
        signature.update(data);
        return signature.verify(sign);
    }
}

base64

  • Base64BcUtils
package com.security.base64;


import org.bouncycastle.util.encoders.Base64;

/**
 * @author fitz
 * @version 1.0
 */
public class Base64BcUtils {

    public static byte[] encode(byte[] bytes) {
        return Base64.encode(bytes);
    }

    public static byte[] decode(byte[] bytes) {
        return Base64.decode(bytes);
    }
}

  • Base64Utils
package com.security.base64;

import java.util.Base64;

/**
 * @author fitz
 * @version 1.0
 */
public class Base64Utils {

    public static byte[] encode(byte[] bytes) {
        return Base64.getEncoder().encode(bytes);
    }

    public static byte[] decode(byte[] bytes) {
        return Base64.getDecoder().decode(bytes);
    }
}

  • UrlBase64Coder
package com.security.base64;

import org.bouncycastle.util.encoders.UrlBase64;

/**
 * @author fitz
 * @version 1.0
 */
public abstract class UrlBase64Coder {

    public final static String ENCODING = "UTF-8";


    public static String encode(String data) throws Exception {

        byte[] b = UrlBase64.encode(data.getBytes(ENCODING));

        return new String(b, ENCODING);
    }

    public static String decode(String data) throws Exception {

        byte[] b = UrlBase64.decode(data.getBytes(ENCODING));

        return new String(b, ENCODING);
    }

}

hash

  • crc
  • MacStreamUtils
package com.security.hash;

import org.apache.commons.codec.digest.DigestUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author fitz
 * @version 1.0
 */
public class MacStreamUtils {

    public static byte[] digest(FileInputStream fis, String type) throws NoSuchAlgorithmException, IOException {
        DigestInputStream dis = new DigestInputStream(fis, MessageDigest.getInstance(type));

        int bufLen = 1024;
        byte[] buffer = new byte[bufLen];
        while (dis.read(buffer, 0, bufLen) > -1) {
        }
        dis.close();

        MessageDigest md = dis.getMessageDigest();
        // can compare with DigestUtils.md5(fis);
        DigestUtils.md5(fis);
        return md.digest();
    }

    public static byte[] digest1(FileInputStream fis, String type) throws NoSuchAlgorithmException, IOException {
        MessageDigest md = MessageDigest.getInstance(type);
        updateDigest(md, fis);
        return md.digest();
    }

    /**
     * ref: DigestUtils md5
     * @param digest
     * @param data
     * @return
     * @throws IOException
     */
    public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
        final int STREAM_BUFFER_LENGTH = 1024;
        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
        int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);

        while (read > -1) {
            digest.update(buffer, 0, read);
            read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
        }

        return digest;
    }




}

  • MacUtils
package com.security.hash;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * mac utils
 * @author fitz
 * @version 1.0
 */
public class MacUtils {

    private static final String HmacMD2 = "HmacMD2";
    private static final String HmacMD4 = "HmacMD4";
    private static final String HmacSHA224 = "HmacSHA224";
    private static final String HmacSHA256 = "HmacSHA256";
    private static final String HmacRipeMD128 = "HmacRipeMD128";
    private static final String HmacRipeMD160 = "HmacRipeMD160";


    public static SecretKey generateSecretKey(String type) throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(type);
        return keyGenerator.generateKey();
    }

    public static byte[] mac(SecretKey key, byte[] bytes) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac mac = Mac.getInstance(key.getAlgorithm());
        mac.init(key);
        return mac.doFinal(bytes);
    }


}

  • MessageDigestUtils
package com.security.hash;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


/**
 * message digest utils.
 * @author fitz
 * @version 1.0
 */
public class MessageDigestUtils {
    private static final String MD2 ="MD2";
    private static final String MD5 ="MD5";
    private static final String SHA ="SHA";
    private static final String SHA_256 ="SHA-256";
    private static final String SHA_384 ="SHA-384";
    private static final String SHA_512 ="SHA-512";

    public static byte[] md2(byte[] bytes) throws NoSuchAlgorithmException {
        return md(MD2, bytes);
    }

    public static byte[] md5(byte[] bytes) throws NoSuchAlgorithmException {
        return md(MD5, bytes);
    }

    public static byte[] sha1(byte[] bytes) throws NoSuchAlgorithmException {
        return md(SHA, bytes);
    }

    public static byte[] sha256(byte[] bytes) throws NoSuchAlgorithmException {
        return md(SHA_256, bytes);
    }

    public static byte[] sha384(byte[] bytes) throws NoSuchAlgorithmException {
        return md(SHA_384, bytes);
    }

    public static byte[] sha512(byte[] bytes) throws NoSuchAlgorithmException {
        return md(SHA_512, bytes);
    }

    private static byte[] md(String type, byte[] bytes) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance(type);
        return md.digest(bytes);
    }

}

  • OtherMessageDigestUtils
package com.security.hash;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

/**
 * @author fitz
 * @version 1.0
 */
public class OtherMessageDigestUtils {
    static {
        if(Security.getProvider("BC") == null ) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    private static final String RipeMD128 ="RipeMD128";
    private static final String RipeMD160 ="RipeMD160";
    private static final String RipeMD256 ="RipeMD256";
    private static final String RipeMD320 ="RipeMD320";
    private static final String Tiger ="Tiger";
    private static final String Whirlpool ="Whirlpool";
    private static final String GOST3411 ="GOST3411";

    public static byte[] RipeMD256(byte[] bytes) throws NoSuchAlgorithmException {
        return md(RipeMD256, bytes);
    }

    private static byte[] md(String type, byte[] bytes) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance(type);
        return md.digest(bytes);
    }
}

certificate

  • 证书生成 openssl 和 keytool操作
echo off

echo 构建目录

mkdir certs
mkdir crl
mkdir newcerts
mkdir private


echo 构建文件
echo 0 > index.txt
echo 01 > serial

echo 构建随机数
openssl.exe rand -out private/.rand 1000

echo 产生私钥
openssl.exe genrsa -out private/ca.key.pem 2048
openssl.exe genrsa -out private/ca1.key.pem 2048
!openssl.exe genrsa -aes256 -out private/ca.key.pem 2048

echo 生成根证书请求 ca.csr
openssl.exe req -new -key private/ca.key.pem -out private/ca.csr -subj "/C=CN/ST=SH/L=PD/O=COM/OU=ANDROID/CN=com.android.security"
openssl.exe req -new -key private/ca1.key.pem -out private/ca1.csr -subj "/C=CN/ST=SH/L=PD/O=COM/OU=ANDROID/CN=com.android.security1"

echo 签发根证书 ca.cer
openssl.exe x509 -req -days 10000 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out certs/ca.cer
openssl.exe x509 -req -days 10000 -sha1 -extensions v3_ca -signkey private/ca1.key.pem -in private/ca1.csr -out certs/ca1.cer

echo 根证书转换 ca.p12
openssl.exe pkcs12 -export -clcerts -in certs/ca.cer -inkey private/ca.key.pem -out certs/ca.p12

echo 颁发服务器证书
openssl.exe genrsa -out private/server.key.pem 2048

echo 生成服务器证书请求 server.csr
openssl.exe req -new -key private/server.key.pem -out private/server.csr -subj "/C=CN/ST=SH/L=PD/O=COM/OU=ANDROID/CN=com.android.security.server"

echo 签发服务器证书 server.cer
openssl.exe x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out certs/server.cer

echo 服务器证书转换 server.p12
openssl.exe pkcs12 -export -clcerts -in certs/server.cer -inkey private/server.key.pem -out certs/server.p12

echo 产生客户私钥
openssl.exe genrsa -out private/client.key.pem 2048

echo 生成客户证书请求 client.csr
openssl.exe req -new -key private/client.key.pem -out private/client.csr -subj "/C=CN/ST=SH/L=PD/O=COM/OU=ANDROID/CN=com.android.security.client"

echo 签发客户证书 client.cer
openssl.exe x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out certs/client.cer
openssl.exe x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca1.cer -CAkey private/ca1.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out certs/client.cer
!openssl.exe ca -in private/client.csr -days 3650 -out certs/client.cer -cert certs/ca.cer -keyfile private/ca.key.pem -notext

echo 客户证书转换 client.p12
openssl.exe pkcs12 -export -inkey private/client.key.pem -in certs/client.cer -out certs/client.p12

echo 根密钥库转换 ca.keystore
keytool -importkeystore -v -srckeystore certs/ca.p12 -srcstorepass 123456 -destkeystore certs/ca.keystore -srcstoretype pkcs12 -deststorepass 123456
keytool -list -keystore certs/ca.keystore -v -storepass 123456

echo 服务器密钥库转换 server.keystore
keytool -importkeystore -v -srckeystore certs/server.p12 -srcstorepass 123456 -destkeystore certs/server.keystore -srcstoretype pkcs12 -deststorepass 123456
keytool -list -keystore certs/server.keystore -v -storepass 123456

echo 客户密钥库转换 client.keystore
keytool -importkeystore -v -srckeystore certs/client.p12 -srcstorepass 123456 -destkeystore certs/client.keystore -srcstoretype pkcs12 -deststorepass 123456
keytool -list -keystore certs/client.keystore -v -storepass 123456

pause

echo on
  • UdpSocket
package com.security.certificate.udpsocket;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;


public class UdpSocket {

    private byte[] buffer = new byte[1024];

    private DatagramSocket receiveSocket;

    private DatagramSocket sendSocket;

    private String remoteHost;

    private int sendPort;

    public UdpSocket(String localHost, String remoteHost, int receivePort,
                     int sendPort) throws SocketException {
        this.remoteHost = remoteHost;
        this.sendPort = sendPort;

        this.receiveSocket = new DatagramSocket(new InetSocketAddress(
                localHost, receivePort));
        this.sendSocket = new DatagramSocket();
    }


    public byte[] receive() throws IOException {
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);

        receiveSocket.receive(dp);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(dp.getData(), 0, dp.getLength());
        byte[] data = baos.toByteArray();
        baos.flush();
        baos.close();
        return data;
    }

    public void send(byte[] data) throws IOException {
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length,
                InetAddress.getByName(remoteHost), sendPort);
        dp.setData(data);
        sendSocket.send(dp);
    }


    public void close() {
        try {

            if (receiveSocket.isConnected()) {
                receiveSocket.disconnect();
                receiveSocket.close();
            }

            if (sendSocket.isConnected()) {
                sendSocket.disconnect();
                sendSocket.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

  • client server
package com.security.certificate.clientserver;

import com.security.certificate.CertificateUtils;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @author fitz
 * @version 1.0
 */
public class Client implements Runnable {
    public static final String PROTOCOL = "TLS";
    private static final String PASSWD = "123456";
    private static final String ip = "127.0.0.1";
    private static final int port = Server.PORT;
    private SSLSocketFactory socketFactory;

    public Client() throws Exception {
        // key manager
        KeyStore keyStore = getKeyManagerStore();
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, PASSWD.toCharArray());

        // trust manager
        KeyStore trustStore = getTrustManagerStore();
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);

        // socket init
        SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        socketFactory = sslContext.getSocketFactory();

    }

    private static KeyStore getKeyManagerStore() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
        InputStream inputStream = Client.class.getResourceAsStream("/certs/client.p12");
        KeyStore keyStore = CertificateUtils.getKeyStore(inputStream, "123456");
        inputStream.close();
        return keyStore;
    }

    private static KeyStore getTrustManagerStore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        InputStream inputStream = Server.class.getResourceAsStream("/certs/ca.cer");
        X509Certificate certificate = (X509Certificate) CertificateUtils.getCertificate(inputStream, "X.509");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", certificate);
        return keyStore;
    }

    @Override
    public void run() {
        int i = 0;
        while(i++ <= 1) {
            try {
                SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(ip, port);
                InputStream is = sslSocket.getInputStream();
                OutputStream os = sslSocket.getOutputStream();
                DataOutputStream out = new DataOutputStream(os);
                out.writeUTF("GET /index.html HTTP/1.0");
                out.flush();

                DataInputStream bin = new DataInputStream(is);
                String ln;
                if ((ln = bin.readUTF()) != null) {
                    System.out.println(ln);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

package com.security.certificate.clientserver;

import com.security.certificate.CertificateUtils;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @author fitz
 * @version 1.0
 */
public class Server implements Runnable {
    private SSLServerSocket serverSocket;
    public static final String PROTOCOL = "TLS";
    private static final String PASSWD = "123456";
    public static final int PORT = 6666;

    public Server() throws Exception {
        // key manager
        KeyStore keyStore = getKeyManagerStore();
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, PASSWD.toCharArray());

        // trust manager
        KeyStore trustStore = getTrustManagerStore();
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);

        // ssl server init
        SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();
        serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(PORT);
        serverSocket.setNeedClientAuth(true);
    }

    private static KeyStore getKeyManagerStore() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
        InputStream inputStream = Server.class.getResourceAsStream("/certs/server.p12");
        KeyStore keyStore = CertificateUtils.getKeyStore(inputStream, "123456");
        inputStream.close();
        return keyStore;
    }

    private static KeyStore getTrustManagerStore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        InputStream inputStream = Server.class.getResourceAsStream("/certs/ca.cer");
        X509Certificate certificate = (X509Certificate) CertificateUtils.getCertificate(inputStream, "X.509");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", certificate);
        return keyStore;
    }


    @Override
    public void run() {
        while (true) {
            try {

                SSLSocket socket = (SSLSocket) serverSocket.accept();
                socket.startHandshake();
//                new Thread(new Runnable() {
//                    @Override
//                    public void run() {
//                        try {
//                            //socket.startHandshake();
//
//
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                });

                OutputStream outputStream = socket.getOutputStream();
                InputStream inputStream = socket.getInputStream();
                DataOutputStream out = new DataOutputStream(outputStream);
                DataInputStream bin = new DataInputStream(inputStream);
                String str = null;
                if((str = bin.readUTF()) != null) {
                    System.out.println(str);
                }

                out.writeUTF("

hello world

"); out.flush(); out.close(); bin.close(); socket.close(); System.out.println(Thread.currentThread().getName()); System.out.println("ssl socket..."); } catch (Exception e) { e.printStackTrace(); } } } }
package com.security.certificate.clientserver;

/**
 * @author fitz
 * @version 1.0
 */
public class ClientServerMain {
    public static void main(String[] args) throws Exception {
        Thread serverThread = new Thread(new Server());
        serverThread.start();
        new Thread(new Client()).start();
    }
}

  • CertificateUtils
package com.security.certificate;

import com.security.signature.SignatureUtils;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * @author fitz
 * @version 1.0
 */
public class CertificateUtils {

    /**
     * p12
     * @param keyStorePath
     * @param passwd
     * @return
     * @throws KeyStoreException
     * @throws IOException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     */
    public static KeyStore getKeyStore(String keyStorePath, String passwd) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream fis = new FileInputStream(keyStorePath);
        keyStore.load(fis, passwd.toCharArray());
        fis.close();
        return keyStore;
    }

    public static KeyStore getKeyStore(InputStream fis, String passwd) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(fis, passwd.toCharArray());
        return keyStore;
    }

    /**
     * p12
     * @param keyStorePath
     * @param passwd
     * @return
     * @throws KeyStoreException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws IOException
     */
    public static KeyStore createKeyStore(String keyStorePath, String passwd) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, passwd.toCharArray());
        FileOutputStream out = new FileOutputStream(keyStorePath);
        keyStore.store(out, passwd.toCharArray());
        out.close();
        return keyStore;
    }

    public static void storeKey(KeyStore keyStore, Key key, String alias, String passwd) throws KeyStoreException {
        keyStore.setKeyEntry(alias, key, passwd.toCharArray(),null);
    }

    public static void storeCertificate(KeyStore keyStore, Certificate certificate, String alias) throws KeyStoreException {
        keyStore.setCertificateEntry(alias, certificate);
    }

    public static PrivateKey getPrivateKey(KeyStore keyStore, String alias, String passwd) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
        return (PrivateKey) keyStore.getKey(alias, passwd.toCharArray());
    }

    public static Certificate getCertificate(KeyStore keyStore, String alias) throws KeyStoreException {
        return keyStore.getCertificate(alias);
    }

    public static PublicKey getPublicKey(Certificate cert) {
        return cert.getPublicKey();
    }

    /**
     *
     * @param certPath
     * @param certType
     *        can be "X.509"
     * @return
     * @throws CertificateException
     * @throws IOException
     */
    public static Certificate getCertificate(String certPath, String certType) throws CertificateException, IOException {
        CertificateFactory certificateFactory = CertificateFactory.getInstance(certType);
        FileInputStream in = new FileInputStream(certPath);
        Certificate certificate = certificateFactory.generateCertificate(in);
        in.close();
        return certificate;
    }

    public static Certificate getCertificate(InputStream is, String certType) throws CertificateException, IOException {
        CertificateFactory certificateFactory = CertificateFactory.getInstance(certType);
        Certificate certificate = certificateFactory.generateCertificate(is);
        return certificate;
    }


    public static byte[] sign(KeyStore keyStore, String alias, String passwd, byte[] data) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, SignatureException, InvalidKeyException {
        PrivateKey privateKey = getPrivateKey(keyStore, alias, passwd);
        X509Certificate certificate = (X509Certificate) getCertificate(keyStore, alias);
        return SignatureUtils.sign(privateKey, data, certificate.getSigAlgName());
    }

    public static boolean verify(X509Certificate certificate, byte[] data, byte[] sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance(certificate.getSigAlgName());
        signature.initVerify(certificate);
        return signature.verify(sign);
    }


}

  • HttpsCertificate
package com.security.certificate;

import javax.net.ssl.*;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * @author fitz
 * @version 1.0
 */
public class HttpsCertificate {

    public static final String PROTOCOL = "TLS";


    /**
     * ssl https best practice
     * ref: https://developer.android.com/training/articles/security-ssl.html?hl=zh-cn
     * @throws Exception
     */
    public static void androidHttps() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        // From https://www.washington.edu/itconnect/security/ca/load-der.crt
        InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
        Certificate ca;
        try {
            ca = cf.generateCertificate(caInput);
            System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
        } finally {
            caInput.close();
        }

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        URL url = new URL("https://certs.cac.washington.edu/CAtest/");
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(context.getSocketFactory());
        InputStream in = urlConnection.getInputStream();
    }


    /**
     * First and major difference between trustStore and keyStore is that trustStore is used by TrustManager
     * and keyStore is used by KeyManager class in Java. KeyManager and TrustManager performs different job
     * in Java, TrustManager determines whether remote connection should be trusted or not i.e. whether remote
     * party is who it claims to and KeyManager decides which authentication credentials should be sent to the
     * remote host for authentication during SSL handshake. if you are an SSL Server you will use private key
     * during key exchange algorithm and send certificates corresponding to your public keys to client, this
     * certificate is acquired from keyStore. On SSL client side, if its written in Java, it will use certificates
     * stored in trustStore to verify identity of Server.
     *
     * @param password
     * @param keyStorePath
     * @param trustStorePath
     * @return
     * @throws Exception
     */
    private static SSLSocketFactory getSSLSocketFactory(String password,
                                                        String keyStorePath, String trustStorePath) throws Exception {

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

        KeyStore keyStore = CertificateUtils.getKeyStore(keyStorePath, password);

        keyManagerFactory.init(keyStore, password.toCharArray());

        TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());

        KeyStore trustStore = CertificateUtils.getKeyStore(trustStorePath, password);

        trustManagerFactory.init(trustStore);

        SSLContext ctx = SSLContext.getInstance(PROTOCOL);

        ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
                .getTrustManagers(), new SecureRandom());

        return ctx.getSocketFactory();

    }


    public static void configSSLSocketFactory(HttpsURLConnection conn,
                                              String password, String keyStorePath, String trustKeyStorePath) throws Exception {

        // 获得SSLSocketFactory
        SSLSocketFactory sslSocketFactory = getSSLSocketFactory(password,
                keyStorePath, trustKeyStorePath);

        // 设置SSLSocketFactory
        conn.setSSLSocketFactory(sslSocketFactory);
    }
}

asn1

util

package com.security.util;

/**
 * @author fitz
 * @version 1.0
 */
public class ByteUtils {
    public static byte[] stringToBytes(String s) {
        if(s == null || s.length() % 2 != 0) {
            return null;
        }
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    public static String bytesToString(byte[] bytes) {
        final char[] hexChars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        char[] chars = new char[bytes.length * 2];
        int byteValue;
        for (int j = 0; j < bytes.length; j++) {
            byteValue = bytes[j] & 0xFF;
            chars[j * 2] = hexChars[byteValue >>> 4];
            chars[j * 2 + 1] = hexChars[byteValue & 0x0F];
        }
        return new String(chars);
    }
}

你可能感兴趣的:(Java密码安全框架)