Java常用的安全算法

    安全算法主要包括 摘要算法、对称加密算法、非对称加密算法、信息编码以及数字签名、数字证书。

1.数字摘要

     数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,由一个单向Hash函数对消息进行计算而产生的。其生产过程如下图所示:


Java常用的安全算法
 有如下特点:

(1)无论输入的消息有多长,计算出来的消息摘要的长度是固定的。应用MD5,计算出长度是128个比特位,使用SHA-1算法计算出来是160个比特位;

(2)只能进行正向的信息摘要,而无法从摘要中恢复出原来的消息。

常用的算法:

MD5及SHA算法。

 java例子:

public class DigestTest {
    public static byte[] testMD5(String content) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(content.getBytes("UTF-8"));
        return bytes;
    }

    public static byte[] testSHA1(String content) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        byte[] bytes = md.digest(content.getBytes("UTF-8"));
        return bytes;
    }

    public static void main(String args[]) throws Exception {
        String content = "123";
        byte[] bytes =  testMD5(content);
        String digest = DatatypeConverter.printHexBinary(bytes);
        System.out.println(digest);

        bytes =  testSHA1(content);
        digest = DatatypeConverter.printHexBinary(bytes);
        System.out.println(digest);
    }

}

 2.对称加密算法

      在对称加密算法中,数据发送方将明文和加密密钥经过特殊加密算法处理后,生成复杂的加密密文进行发送,数据接收方收到密文后,必须用相同的算法及密钥时行解密。其过程如下:


Java常用的安全算法
 特点是算法公开、计算量小、加密速度快,加密效率高。

常用的加密算法包括:DES算法、3DES算法、AES算法。

Java例子:

AES对称算法加密:(用DES算法,只需要把AES改成DES即可)

public class AESTest {
    public static String genKeyAES() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128);
        SecretKey key = keyGenerator.generateKey();
        String base64Key =  DatatypeConverter.printBase64Binary(key.getEncoded());
        return base64Key;
    }
    public static SecretKey loadKeyAES(String base64Key){
        byte[] bytes = DatatypeConverter.parseBase64Binary(base64Key);
        SecretKey key = new SecretKeySpec(bytes, "AES");
        return key;
    }

    public static byte[] encryptDES(byte[] source, SecretKey key) throws Exception {
        Cipher ciper = Cipher.getInstance("AES");
        ciper.init(Cipher.ENCRYPT_MODE, key);
        byte[] bytes = ciper.doFinal(source);
        return bytes;
    }

    public static byte[] decrytDES(byte[] source, SecretKey key) throws Exception{
        Cipher ciper = Cipher.getInstance("AES");
        ciper.init(Cipher.DECRYPT_MODE, key);
        byte[] bytes = ciper.doFinal(source);
        return bytes;
    }

    public static void main(String args[]) throws Exception {
        String test = "1234";
        String content = genKeyAES();//"12345678901234567890123456789012";
        System.out.println(content);

        SecretKey secretKey = loadKeyAES(content);

        byte bytes[] =  encryptDES(test.getBytes(), secretKey);
        System.out.println("secretKey String:" + DatatypeConverter.printHexBinary(bytes));

        bytes = decrytDES (bytes, secretKey);
        System.out.println("decrytDES String:" + new String(bytes));


    }
}

 

3.非对称加密算法

    又称为公开密钥加密算法,需要两个密钥,一个是公开密钥(public key),一个是私有密钥(private key),公钥和私钥需要配对使用。

    基本过程:甲方生成一对密钥,并将其中的一把作为公钥向其他人公开,得到该公钥的乙方使用该密钥对机密信息进行加密后再发送给甲方,甲方再使用自己保存的另一把密钥(即私钥)对加密后的信息进行解密。如下图所示:


Java常用的安全算法
 

常用的算法:RSA算法

JAVA的例子:

public class RSATest {
    public static KeyPair getKeyPairt() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(512);
        return keyPairGenerator.generateKeyPair();
    }
    public static String getPublicKey(KeyPair keyPair){
        PublicKey publicKey = keyPair.getPublic();
        byte[] bytes = publicKey.getEncoded();
        return DatatypeConverter.printBase64Binary(bytes);
    }
    public static String getPrivateKey(KeyPair keyPair){
        PrivateKey privateKey = keyPair.getPrivate();
        byte[] bytes = privateKey.getEncoded();
        return DatatypeConverter.printBase64Binary(bytes);
    }
    public static PublicKey String2Publickey(String pubStr) throws Exception {
        byte[] bytes = DatatypeConverter.parseBase64Binary(pubStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory  keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }
    public static PrivateKey String2Privatekey(String privateStr) throws Exception {
        byte[] bytes = DatatypeConverter.parseBase64Binary(privateStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory  keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privatekey = keyFactory.generatePrivate(keySpec);
        return privatekey;
    }

    public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(content);
    }

    public static byte[] privateEncrypt(byte[] content,  PrivateKey privatekey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privatekey);
        return cipher.doFinal(content);
    }

    public static byte[] publicDecrypt(byte[] content, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(content);
    }
    public static byte[] privateDecrypt(byte[] content, PrivateKey privatekey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privatekey);
        return cipher.doFinal(content);
    }


    public static void main(String[] args) throws Exception {
        String str = "Hello, I am lai xiao hong";
        byte[] bytes = str.getBytes();
        KeyPair keyPair = getKeyPairt();
        String publicKey = getPublicKey(keyPair);
        String privateKey = getPrivateKey(keyPair);
        System.out.println("publicKey:" + publicKey);
        System.out.println("privateKey:" + privateKey);

        //byte[] encBytes = publicEncrypt(bytes, String2Publickey(publicKey));
        //byte[] decBytes = privateDecrypt(encBytes,String2Privatekey(privateKey));
        byte[] encBytes = privateEncrypt(bytes, String2Privatekey(privateKey));
        byte[] decBytes = publicDecrypt(encBytes, String2Publickey(publicKey));

        System.out.println("Decrypt String:" + new String(decBytes));

    }
}

4.数字签名

    签名认证是对非对称加密技术和数字摘要技术的综合运用,指的是将通信内容的商要信息使用发送者的私钥进行加密,然后将密文与原文一起传输给信息的接收者,接收者通过发送者的公钥解密被加密的摘要信息,然后使用与发送者相同的摘要算法,对接收的内容采用相同的方式产生摘要串,与解密的摘要串进行对比,如果相同,则说明接收到的内容是完整的,在传输过程中没有受到第五方篡改,否则说明通信内容已被第三方修改。

    只有信息的发送者才能产生别人无法篡改的数字签名串,这个串能对信息发送者所发送的内容完整 性和发送者的身份进行校验和签别,通信正文经过相应的摘要算法生成摘要后,使用消息发送者的私钥进行加密,生成数字签名如下图所示:


Java常用的安全算法
 

    消息的接收端收到信息的正文和对应的数字签名后,使用与发送端相同的摘要算法,生成通信正文的摘要,并且使用发送者的公钥对数字签名进行解密,得到发送商生成的摘要,进行比较后即可验证发送者的身份是否合法,正文内容是否被篡改,如下图所示:


Java常用的安全算法
 

 常风的数字数字签名算法包括:MD%withRSA、SHA1withRSA等.

java 例子:

public class SignatureTest {
    private static byte[] sign(byte[] content, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(privateKey);
        signature.update(content);
        return  signature.sign();
    }
    private static boolean verify(byte[] content,byte[] sign, PublicKey publicKey)  throws Exception{
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(publicKey);
        signature.update(content);
        return signature.verify(sign);
    }
}

5.数字证书

    也称为电子证书,通常包含如下内容:

  • 对象的名称
  • 证书的过期时间
  • 颁发机构
  • 签名算法
  • 对象的公钥

    大多数证书采用X.509的格式来保存证书,数字证书的签发过程实际上就是对数字证书的内容,包括证书所代表对象的公钥进行数字签名,而验证证书的过程,实际上是检验证书的数字签名。

    在现实中,网络用户的数字证书需要数字认证机构(Certificate Authority,CA)来进行颁发,只有经过CA颁布的数字证书在网络中才具备认证性。

证书的生成过程如下:


Java常用的安全算法
 

证书的验证过程如下:



Java常用的安全算法
 
     要获得数字证书,首先需要使用数字证书管理工具,如keytool,OpenSSL等,然后构建CSR(Certificate Signing Request)数字证书签发申请,提交给数字证书认证机构进行签名,最终形成数字证书。

相关推荐