+ Asymmetric encryption symmetric encryption, data security transmission

General financial product, it comes front and rear interaction, we will have strict data security. Prevent hacker attacks, information tampering.

There are many encryption, in general, divided into two kinds: symmetric and asymmetric. Let's look at these two encryption methods are what is? What are their differences?

Symmetric encryption:

Symmetric encryption, i.e. symmetric cryptographic encoding technique, he is characterized, using the same encryption and decryption keys.

Common symmetric encryption algorithms DES, 3DES, Blowfish, IDEA, RC4, RC5, RC6 and AES. Symmetric encryption algorithm is simple and quick to use, the key short and difficult to decipher.

However, symmetric secret key the following problems during use:

1, symmetric encryption algorithms typically do not provide the integrity of the authentication information. It can not verify the identity of the sender and the recipient;

2, symmetric key management and distribution work is a potentially dangerous and cumbersome process. How to prevent leakage of secret key is a difficulty.

Asymmetric encryption:

Asymmetric cryptography, two keys, public and private keys. Public and private key pairs.

If the public key to encrypt data, using only the corresponding private key can decrypt; if the private key used to encrypt the data, then only decrypted with the corresponding public key can. Because the encryption and decryption using two different keys, so this algorithm is called asymmetric encryption algorithm.

The basic process of asymmetric encryption algorithm confidential information is exchanged: one party generating a pair of keys and wherein the other party is disclosed as a public key; obtaining the public key using the key B of confidential information encrypted and then sent to the owner; then the other party of their own to save the private key to decrypt the encrypted information. Party A can use its private key to decrypt any information by the public key encryption.

Typical applications of asymmetric encryption is a digital signature.

Common asymmetric encryption algorithms: RSA, ECC (mobile equipment), Diffie-Hellman, El Gamal, DSA (digital signature).

+ Asymmetric Symmetric combination:

Now, we have some understanding of symmetric and asymmetric encryption. Next, I'll tell you about a way encryption I used in the project: Symmetrical + asymmetrical.

A look at the flow chart:

Look at the sender:

Here, we are mainly two-step operation.

1、报文原文使用对称加密技术。对称加密的秘钥(避免混淆,这里称对称密码)。根据随机数生成。每次发起请求时,会重新产生一个随机数,进一步降低被破解的风险。

2、对称密码通过非对称加密方式进行加密。公钥由后台产生,匹配的私钥由后台保管。这样产生一个加密后的对称密码。前端在发送给后端之后,后端需要用匹配的私钥才能解开。

再看接收方:

接收方在接收到数据包之后,同样有两步操作:

1、会使用匹配的私钥解密加密的对称密码,获取到真实的对称密码。

2、使用对称密码,解密加密报文,获取原报文内容。

这样做的好处是:

1、因为我们的对称密码是使用非对称加密的,因此,想要破解,需要找到相应的公钥才行。

2、每次请求会重新生成一个对称密码,这就加大了破解的难度。

代码实现:

工具类:

非对称加密:

public class RSA1 {
    /**
     * 随机生成公钥和私钥
     */
 
    public static final String publicKeyString  = "publicKeyString";
    public static final String privateKeyString = "privateKeyString";
 
 
    public static HashMap<String, String> getRandomKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);//生成大小 1024
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//获取公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//获取私钥
        HashMap<String, String> keyMap = new HashMap<String, String>();
        keyMap.put(publicKeyString, new String(Base64.encode(publicKey.getEncoded(), Base64.DEFAULT)));//获取公钥Base64编码
        keyMap.put(privateKeyString, new String(Base64.encode(privateKey.getEncoded(), Base64.DEFAULT)));//获取密钥Base64编码
        return keyMap;
    }
 
    /**
     * 通过字符串生成私钥
     */
    public static PrivateKey getPrivateKey(String privateKeyData) {
        PrivateKey privateKey = null;
        try {
            byte[] decodeKey = Base64.decode(privateKeyData, Base64.DEFAULT); //将字符串Base64解码
            PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//创建x509证书封装类
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA
            privateKey = keyFactory.generatePrivate(x509);//生成私钥
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }
 
 
    /**
     * 通过字符串生成公钥
     */
    public static PublicKey getPublicKey(String publicKeyData) {
        PublicKey publicKey = null;
        try {
            byte[] decodeKey = Base64.decode(publicKeyData, Base64.DEFAULT);
            X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return publicKey;
    }
 
    /**
     * 加密
     */
    public static byte[] encrypt(String data, Key key) {
        try {
            //取公钥
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm(),"BC");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(data.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 解密
     */
    public static byte[] decrypt(byte[] data, Key key) {
        try {
            Cipher cipher = Cipher.getInstance("RSA","BC");
            cipher.init(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

对称加密:

public class AES_2 {
 
    public static byte[] genPrivateKey(String password) throws NoSuchAlgorithmException {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        byte[] bytes = tohash256Deal(password);
        SecureRandom securerandom = new SecureRandom(bytes);
        kgen.init(128, securerandom);
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        return key.getEncoded();
    }
 
    public static byte[] encrypt(String content, SecretKeySpec key) {
        try {
            //创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] byteContent = content.getBytes("utf-8");
            byte[] cryptograph = cipher.doFinal(byteContent);
            return Base64.encode(cryptograph, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static String decrypt(byte[] cryptograph, SecretKeySpec key) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT));
            return new String(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static byte[] encrypt(String content, String password) {
        try {
            //"AES":请求的密钥算法的标准名称
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            //256:密钥生成参数;securerandom:密钥生成器的随机源
            SecureRandom securerandom = new SecureRandom(tohash256Deal(password));
            kgen.init(128, securerandom);
            //生成秘密(对称)密钥
            SecretKey secretKey = kgen.generateKey();
            //返回基本编码格式的密钥
            byte[] enCodeFormat = secretKey.getEncoded();
            //根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            //将提供程序添加到下一个可用位置
            Security.addProvider(new BouncyCastleProvider());
            //创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
            //"AES/ECB/PKCS7Padding":转换的名称;"BC":提供程序的名称
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] byteContent = content.getBytes("utf-8");
            byte[] cryptograph = cipher.doFinal(byteContent);
            return Base64.encode(cryptograph, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static String decrypt(byte[] cryptograph, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            SecureRandom securerandom = new SecureRandom(tohash256Deal(password));
            kgen.init(128, securerandom);
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT));
            return new String(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }
 
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }
 
    public static byte[] tohash256Deal(String datastr) {
        try {
            MessageDigest digester = MessageDigest.getInstance("SHA-256");
            digester.update(datastr.getBytes());
            byte[] hex = digester.digest();
            return hex;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
 
}

发送方和接收方的实现:

String content = "000";
JSONObject jsonObject = new JSONObject();
try {
    LogT.i("++++++++++++++++++++++发送方+++++++++++++++++++++++++=");
    //产生私钥
    int random = (int) ((Math.random() * 9 + 1) * 100000);
    //私钥字节
    byte[] bytes = AES_2.genPrivateKey(String.valueOf(random));
    //传输报文加密
    SecretKeySpec key1 = new SecretKeySpec(bytes, "AES");
    byte[] content_encrypt = AES_2.encrypt(content, key1);
    //公钥对私钥加密
    PublicKey publicKey = RSA1.getPublicKey(public_key);
    sKey_encrypt = RSA1.encrypt(Base64.encodeToString(bytes, Base64.DEFAULT), publicKey);
    //数据组装
    jsonObject.put("key", Base64.encodeToString(sKey_encrypt, Base64.DEFAULT));
    jsonObject.put("content", AES_2.parseByte2HexStr(content_encrypt));

    LogT.i("+++++++++++++++++++++++接收方++++++++++++++++++++++++=");

    //解析获取私钥
    PrivateKey privateKey = RSA1.getPrivateKey(private_key);
    //解析接收到的key数据
    byte[] decode = Base64.decode(Base64.encodeToString(sKey_encrypt, Base64.DEFAULT), Base64.DEFAULT);
    //私钥解密
    byte[] decrypt = RSA1.decrypt(decode, privateKey);
    //解码私钥字节
    byte[] decode_orig = Base64.decode(new String(decrypt), Base64.DEFAULT);
    //加密的报文
    byte[] HexStrByte = AES_2.parseHexStr2Byte(AES_2.parseByte2HexStr(content_encrypt));
    SecretKeySpec key2 = new SecretKeySpec(decode_orig, "AES");
    //解密后的报文
    String decrypt1 = AES_2.decrypt(HexStrByte, key2);
    LogT.i(decrypt1);//000
} catch (Exception e) {
        e.printStackTrace();
}

参考:

原文:https://blog.csdn.net/Aminy123/article/details/81871092 

Guess you like

Origin www.cnblogs.com/eternityz/p/12239319.html