Serie de seguridad: ¿cuántas personas pueden identificar la clave pública y la clave privada de RSA? ¿Cómo utilizar las claves públicas y privadas para la verificación, el cifrado y el descifrado de firmas RSA?

Al conectarse con las plataformas de desarrollo de muchas empresas de Internet, la seguridad de sus propias plataformas en el futuro requerirá la firma de la persona que llama para confirmar que la identidad de la persona que llama es legal. Al mismo tiempo, la seguridad de la transmisión de la red de información en el futuro también puede requieren cifrado y descifrado. Por ejemplo, cuando se conecta a las plataformas abiertas Alipay y WeChat, debe configurar la clave pública y descargar la clave pública de la plataforma. La persona que llama posteriormente debe firmar el mensaje solicitado. Después de que Alipay y WeChat reciban la solicitud, deben verificar la firma. Sólo cuando se pasa la verificación de identidad se puede ejecutar. Procesos de negocio relacionados.

En el proceso de desarrollo real, muchas personas están confundidas acerca de qué es una clave pública y qué es una clave privada, cómo realizar la verificación, el cifrado y el descifrado de firmas, y cuál es la relación entre la verificación de firmas y el cifrado y descifrado. En este número, hablaremos de este tema en detalle. Para el algoritmo RSA, consulte mi artículo "Security Series-RSA Past and Present", el cifrado y el descifrado pueden consultar mi artículo "Security Series-Handwritten JAVA Encryption and Decryption".

Uno, clave pública y clave privada

En el artículo anterior "Security Series-Handwritten JAVA Encryption and Decryption", se introdujeron el cifrado simétrico y el cifrado asimétrico. Entre ellos, el cifrado asimétrico utiliza el algoritmo RAS. El denominado asimétrico significa que la clave secreta utilizada para el cifrado es diferente de la clave secreta utilizada para el descifrado. En otras palabras, RSA tiene un par de claves secretas, una es una clave pública, la otra es una clave privada, una se usa para encriptar y la otra se usa para desencriptar.

Las dos aplicaciones del algoritmo RAS son la verificación de firmas, el cifrado y el descifrado.

Antes del intercambio de claves públicas

En el proceso de comunicación de la red, antes de la comunicación, tanto la persona que llama como la persona que llama deben generar un par de claves públicas y privadas; luego, la persona que llama y la persona que llama intercambian claves públicas; de modo que la persona que llama y la persona que llama tienen sus propias claves privadas. claves y La clave pública de la otra parte, que se utiliza para la verificación de firmas y el cifrado y descifrado para la seguridad de las comunicaciones.

Después del intercambio de claves públicas

La clave privada solo puede ser propiedad de uno mismo y no puede exponerse a nadie. Siempre que la clave privada no esté expuesta, la comunicación es segura. La clave privada puede ser equivalente a la identidad.

Cualquiera puede obtener la clave pública. Después de obtener la clave pública de la otra parte, la firma de la otra parte puede ser verificada por la clave pública; al mismo tiempo, la clave pública de la otra parte se usa para el cifrado y solo puede ser descifrada por el privado. clave de la otra parte.

Debido a que la clave pública es pública, también facilita el intercambio de claves públicas entre las partes que se comunican, por lo que no es necesario considerar si se filtra durante el intercambio.

2. La relación entre la verificación de firmas y el cifrado y descifrado

En primer lugar, se enfatiza que no existe relación entre la verificación de firmas y el cifrado y descifrado .

La verificación de firmas y el cifrado y descifrado son medidas necesarias para la seguridad del sistema, pero para prevenir diferentes riesgos de seguridad.

Verificación de firma

Verificación de firma: para verificar si la identidad del usuario es legal. Por ejemplo, el pago de WeChat, cualquier comerciante legítimo puede llamar a la interfaz de pago de WeChat. Entonces, ¿qué es un comerciante legal? Cumplir con muchos requisitos de WeChat, como los comerciantes que se registran en la plataforma de comerciantes de WeChat para obtener una identificación de comerciante, la firma de productos de pago relacionados para obtener el ID de aplicación, la configuración de la clave pública del comerciante para los productos de pago abiertos y la descarga de la clave pública de WeChat. Dichos comerciantes son solo para WeChat. Legal. Luego, el comerciante usa su propia clave privada de comerciante para firmar los parámetros de solicitud relevantes y luego llama a la interfaz de pago de WeChat; después de recibir la solicitud, WeChat verifica la solicitud a través de la clave pública del comerciante configurada por el comerciante en la plataforma , y la verificación lo indica. Cuando lo inicia un comerciante de plataforma legítimo, se pueden realizar servicios de pago específicos después de que se haya pasado la verificación.

Verificación de firma

¿Por qué se utiliza la clave privada de la persona que llama para la firma? La firma suele ser que la persona que llama (plataforma) requiere que la persona que llama firme en consideración a su propia seguridad, para verificar si la persona que llama es legal. Se considera la seguridad del destinatario. Debido a que el comerciante legítimo ya ha configurado su clave pública para el backend de WeChat, cuando una persona que llama pasa los parámetros firmados a la plataforma WeChat, y la plataforma WeChat puede usar la clave pública configurada por el comerciante para verificar la firma, lo que indica que la solicitud es made Una persona es un comerciante legítimo que posee esta clave privada, porque solo el comerciante que posee esta clave privada puede realizar esta firma. La clave privada es confidencial y no todos la tienen. Si la firma usa una clave pública, todos pueden obtener la clave pública de Internet. Una persona que llama ilegalmente también puede obtener la clave pública y firmar una solicitud a WeChat. Incluso si la plataforma WeChat pasa la verificación, no se sabe si la persona que llama es legítimo.

cifrar y decodificar

Cifrado y descifrado: para evitar que los datos sean secuestrados durante la transmisión de la red. Si el comerciante llama a la interfaz de pago de WeChat, hay muchos campos confidenciales en el mensaje de solicitud, como el número de tarjeta bancaria, contraseña, etc. (estos campos no son realmente necesarios). Cuando el mensaje se transmite en la red, es maliciosamente monitoreado, lo que hará que el comerciante se filtre el número de tarjeta bancaria y la contraseña, por lo que el comerciante debe usar la clave pública de WeChat para cifrar todo el mensaje al llamar ; después de que WeChat recibe la solicitud, puede usar la clave privada de WeChat para descifrar , que puede evitar que se filtre información confidencial. Por supuesto, https se ha cifrado durante la transmisión.

cifrar y decodificar

¿Por qué utilizar la clave pública de la otra parte para el cifrado? La encriptación generalmente la realiza la persona que llama (comerciante) teniendo en cuenta su propia seguridad para garantizar que la información confidencial de la persona que llama no se filtre y que solo el verdadero destinatario pueda desencriptarla. ¿Cómo garantizarlo? Es decir, incluso si la información es secuestrada durante la transmisión de la red, no se puede descifrar. Si desea descifrar, debe mantener la clave secreta. Si desea mantener solo la clave secreta, debe ser la clave privada, porque la clave privada no es pública. Se puede descifrar, indicando que esta información le sucedió. Por tanto, a quién se envía la información sólo se le puede descifrar con cuya clave privada, lo que requiere que el remitente la cifre con su clave pública. Para enviar información a la plataforma WeChat, debe estar encriptada con la clave pública de la plataforma WeChat.

Aquí, la verificación de firmas y el cifrado y descifrado utilizan diferentes claves públicas y privadas. Al firmar, desde la perspectiva de la persona que llama (plataforma WeChat), a quien WeChat requiere que llame a la plataforma WeChat, quién usa su propia clave privada para firmar; al descifrar, desde la perspectiva de la persona que llama (comerciante), el comerciante envía la información A quién, quién puede usar su clave privada para descifrar. Debido a que solo usted tiene la clave privada, la clave privada se puede equiparar con usuarios legítimos. La clave pública está abierta a toda la red y cualquiera puede obtenerla.

para resumir:

Firma: cuando A llama a B, B debe verificar si A es legal (si puede llamar a la interfaz) y A debe firmar con su propia clave privada;

Descifrado: cuando A llama a B, A debe verificar si B es legal (si se puede descifrar) y B debe usar su propia clave privada para descifrar;

Tres, prueba

Esto simula el proceso de A enviando un mensaje a B. Antes de la prueba, A genera un par de claves públicas y privadas, B genera un par de claves públicas y privadas, y luego A y B intercambian claves públicas, A tiene privateKey_A y publicKey_B y B tiene privateKey_B y publicKey_A. Aquí solo se simulan la verificación de firma unidireccional (A solicitud B) y el cifrado y descifrado, y aquellos que estén interesados ​​pueden simular la verificación de firma bidireccional (A solicitud B y B respuesta A) y el cifrado y descifrado por sí mismos.

Para la generación de claves públicas y privadas, consulte el artículo anterior "Serie de seguridad: cifrado y descifrado JAVA manuscrito". Siga la cuenta oficial e ingrese la palabra clave " java-summary " para obtener el código fuente.


/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-08-21
 */
@Slf4j
public class SignAndEncryptTest {
    
    

    public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
    public static final String CHATSET = "utf-8";

    public static String publicKey_A = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnen01CdQc2zh/HihCNNYI6u7AFXf/NrZ/9auPvFsJcK1cWj5EFBU3lrts2OTvrmYVurhABg2g/Ya7glzUt6DwUojHOWtpwFxSH1v7FUJMvxDsbd4GXKRdWqMkqkcCMQYDpGpshbL3IAWYIw6pgnBcKksbzkDrZCZMAyHa1bB3zh5uEm9mcrRlBUGirbPNVt++3ztIfdc4Vp5hbw++daNMFr/VGDohMVg3Dlk4ZktDgHc5nakXkE8hSr6UDTw45JpfZZ0dP9XTi/CSVQdoYD+dsJIZ8uletlbrErRfZEJNx/k0w88P4kfGteNBGhlzzVo45tMkHT33O8QB6JxI4xVQIDAQAB";
    public static String privateKey_A = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyd6fTUJ1BzbOH8eKEI01gjq7sAVd/82tn/1q4+8WwlwrVxaPkQUFTeWu2zY5O+uZhW6uEAGDaD9hruCXNS3oPBSiMc5a2nAXFIfW/sVQky/EOxt3gZcpF1aoySqRwIxBgOkamyFsvcgBZgjDqmCcFwqSxvOQOtkJkwDIdrVsHfOHm4Sb2ZytGUFQaKts81W377fO0h91zhWnmFvD751o0wWv9UYOiExWDcOWThmS0OAdzmdqReQTyFKvpQNPDjkml9lnR0/1dOL8JJVB2hgP52wkhny6V62VusStF9kQk3H+TTDzw/iR8a140EaGXPNWjjm0yQdPfc7xAHonEjjFVAgMBAAECggEAec/qIPXZIF0CuTuEXKSr38gD5NpVmuPO38EPb0uJ96pgnuCzqMxRhmRN/Qv4ojfmn3UucH7BnJVMJtoeEy39NdtTfeo3aJS963vufNTQlf0NoARk1RElKt1XudPwwQlt2ABu0M/YTV4GlxGhyb3ohKoCN76x+si0MIhurIryovyabZCtlhGD2fg3V1t8RBlCEuz68FtB9fSh4zk7u6RhAL5LCOGNbVAiY4hx/NhrDiBfvQBhJZmPG+3gWjjZFgZEH5B0tGByuG2M+dj2qT5LFepkhGyI/upJwOhJrjiRrvR7LmSYCz0lI8/2fVCF8jN/TJav/1xVR82d/165Movm0QKBgQDZv/H1bhPoCoeh8z3ww8Um5FjFb1MMjmh4oB1d2+0QlYTbSVx6mOxBoh0yk+jKztotJyWs61nnHekOhdHFx9Ij1L8oMxybBK+heTuzl2WIs9/2CRBV4XfKMwNiYxJYkaXxUgeHx/2IVXTuFMKMrWhf7kxk2iFrK+Gv63oY0dmvhwKBgQDR0TWXRXC2qEqH/NV/6d24UHl4i/+UP1aKE9jA8xArJYBlKtTWCgM7g3/wxr0IRB6RocVupop/kZJ9RUFjprfaykDOj+A0oC+IDwUmGIjGbR4P921qjWEVQGIFSJvnIwHwGfEAPxvw0uW2tqz9C2GUZ9OB17lecfIdeJQX2Hb3QwKBgA9bWCclAkZlJ7emPgIS7H6XsCMMfODv0jJfqHKMJiX7RYlpnRoQWukuE70TbWGQQRbaIfAWERsZouwhR/AY7ZsVT/33zNap9/D9adZ6oPCJLwxdC0fjRN1/x4dS0WJpszhXvqw20Iyi6kI4OJhPSoMpfT3HnH/AcoRDqTLC6gVVAoGBAI3f9GfseZHZbERV75wF7HoEWI7tw41f4smNMAUQln9GZXKDKtXsgVEN00ZhbFMZlL4O8GyoyoAGVFLGsLeMdUfJeVbzrLyJEHrlBStEbcAW6rwLJ/5jySDQnzdJaLo7TsUnFXKAOgl24gPRtFmLB5mNN1TWJS86x2esMB+LrK33AoGADEDHIUtulc4zclLH9MJj7JcZPkgVz5llJ1jQj3fOu4iPc9TNvV2gV2kWU446gyMmRrQ2We1awnrjaeSzeFnf0OhL+yTzNUmRLMYWZhja/KMhr7b9vVRCCrysZJod+MWodEH+HIJlu9RGIxv7fNNy1S4yRU92OQU43XQ1S93eaEE=";

    public static String publicKey_B = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv8GjRufWGPI7Xe6caZ5h5PbnRIQVzD4P1gDjKZaibcxcApGEaqFkT3Am2U6iKv6paELuwxy+dUL1Jvbs09QljuHgDB9SV0VxSM5LscpCmWJ5P1V6Y/QiholCQHCFR6ok6oE2HWGRw/bPQWr/gHfa2zNPu+CB64cbOxLHIQYIRji47tyywAL5ABhF1msZY2vW8xaFKHGq74sxNpf8s0NUnRnVRANjHtuDa/zvrHim45gqBWg+3gPVSQyPU3ydMoj0AiORJQmqprHaZDB7BufpTEZA6I2WElsKJcsGMdwfSd1s0B1iCzrkMmT30n/XXxyw8qQGsvJvQ2V90QiAV9bV+wIDAQAB";
    public static String privateKey_B = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/waNG59YY8jtd7pxpnmHk9udEhBXMPg/WAOMplqJtzFwCkYRqoWRPcCbZTqIq/qloQu7DHL51QvUm9uzT1CWO4eAMH1JXRXFIzkuxykKZYnk/VXpj9CKGiUJAcIVHqiTqgTYdYZHD9s9Bav+Ad9rbM0+74IHrhxs7EschBghGOLju3LLAAvkAGEXWaxlja9bzFoUocarvizE2l/yzQ1SdGdVEA2Me24Nr/O+seKbjmCoFaD7eA9VJDI9TfJ0yiPQCI5ElCaqmsdpkMHsG5+lMRkDojZYSWwolywYx3B9J3WzQHWILOuQyZPfSf9dfHLDypAay8m9DZX3RCIBX1tX7AgMBAAECggEBAIkRYyMGCTYfwGvuagPdYOCH1NxXBjXOjwdL7xUFRenyUDrNxbdq0gcuhbaDzMuq6XFLltwFKecsC4zkqHjqhkZSExLXOMaFLur5+4WErIJzr3OkKC5Wjm9YofDp/XsyldzCq+nomodXXuLGFwi/o8NYNEB5xKSVGNPrIkfqxfNazdR63738zq0ZPQmMjxEb/AK5uc+fdF9qosDrNI0SqQng00mhfpilvwHZbOYPfKNfh26lpqTEAGk0gaFGfr/QnhUDAnxfaoLhr9zELr4utrkwpaCzX958MrRB5naeScocYSl1h4Bi6htjjpdLWDKkk/vQ8Keno6GtF9Iha8MdvnECgYEA9p5UzaP3qYek4pe96milqmPiYkQeqSAUWSp1TpC5ppIoyPGMYl7Ia8SOsIYBw+9WL9iIR6jqZOpd/E68j8YsW5PyJuFYQTVjXZrVD76D435mskl4gsKz1izEWz5jzU/oE4mGfuaobfaOuw5ixun7dd8FrXknIVHbne0zyEZ+FY0CgYEAxw0Jq3aJbrJHX8ahPsZAodbWKYH8Ojkt2GkXKdrB9HJ6EGKockjPj7R/+ForXw2XWoGdoL4QPalhKuJX+3bsSQIgt7mDRiDEPK7XkbKd5mS/HTXWXsTIkGaDhYlq6yOkbmRsR3QgCfnhLYaaYkZ6kIKDsGgUJF8oIqxKrlDWo6cCgYBUyulzbu3nLwklE3Er2GElbYRXrv4vviTg53U/1wjN2bEGLe7Ln7UfQIyi6uBOgsrKVpO8t7onimFYL6YrdMKplfuLHK2gdf+9HlAlQqbMIBilMheqNdFpUSkOCix8Wf38QauplBrS/BPlArQ5mhdoVo74LxCiJyfwa68DLCGLvQKBgEGg4tdNtfJxhWbmrrNr2lOB6gq1eNwZjiwUOjbqkZhvRh+w56kGqKjQ8oCH+lTUvlpw8e/VurUZ65egGTIn+6/2q6Ln34h3tTvsydaX9cfI39pZrdyBNT+nDSYyMLZmggiDw8+rUgT4Bm5kOvK8Gh0bax/2sO1tEmacN+NRc/NxAoGALzEnmKI9B46NVNOWi0VLtTdiloSI6bxgli0Rm8T+6wD6y9JNnWsibYydGx9pDn6w2qihuP1QcKruHUiZ7V8aahhD4o4e/a+IgRzNYcQh4CngUzL+XymlqQVbDSaiEiVi/qSNv+i9mgeF/mSYbYcZjhFPjzdOy3hvtO3GtjDSMQw=";

    // 封装发送的消息
    public static Map<String,String> communicationParams = null;

    public static void main(String[] args) {
    
    

        // A给B发消息
        ASendMsgToB();

        // B接收来自A的消息
        BReceiveFromA();
    }


    /**
     * A给B发消息,首先A-B交换公钥,A拥有 privateKey_A 和 publicKey_B
     *
     * A使用publicKey_B加密消息,再使用privateKey_A对密文签名,然后将密文和签名发给B
     */
    public static void ASendMsgToB(){
    
    

        // 消息明文
        String msg = "你好";

        // 加密
        String encryptMsg = encryptByPublicKey(msg,publicKey_B);

        // 签名
        String sign = signByPrivateKey(encryptMsg,privateKey_A);

        // 发送消息
        communicationParams = new HashMap<String,String>();
        communicationParams.put("encryptMsg",encryptMsg);
        communicationParams.put("sign",sign);
        log.info("A发送给B的消息:{}", JSON.toJSONString(communicationParams));

        log.info("-------------------------------------------------");
    }

    /**
     * B接收A的消息,首先A-B交换公钥,B拥有 privateKey_B 和 publicKey_A
     *
     * B收到消息后,先使用publicKey_A验签,再使用privateKey_B解密
     */
    public static void BReceiveFromA(){
    
    
        // 接收消息
        Map<String,String> receiveMsg = communicationParams;
        log.info("B接收到A的消息:{}", JSON.toJSONString(receiveMsg));
        String sign = receiveMsg.get("sign");
        String encryptMsg = receiveMsg.get("encryptMsg");

        // 验签
        Boolean tf = verifySignPublicKey(encryptMsg,publicKey_A,sign);
        if(tf){
    
    
            log.info("验签通过,说明这个信息是B认可的用户发来的");
        }

        // 解密
        String msg = decryptByPrivateKey(encryptMsg,privateKey_B);
        log.info("解密成功,说明这个信息就是发给B的");


        log.info("B收到的消息:{}", msg);
    }


    /**
     * RSA签名
     * @param content 待签名数据
     * @param privateKey 商户私钥
     * @return 签名值
     */
    public static String signByPrivateKey(String content, String privateKey)
    {
    
    
        try{
    
    
            PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
            KeyFactory keyf                 = KeyFactory.getInstance("RSA");
            PrivateKey priKey               = keyf.generatePrivate(priPKCS8);

            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update( content.getBytes(CHATSET) );

            byte[] signed = signature.sign();

            return Base64.encode(signed);

        }catch (Exception e){
    
    
            log.error(e.getMessage(), e);
        }

        return null;
    }

    /**
     * RSA验签名检查
     * @param content 待签名数据
     * @param sign 签名值
     * @param publicKey 公钥
     * @return 布尔值
     */
    public static boolean verifySignPublicKey(String content, String publicKey, String sign)
    {
    
    
        try{
    
    
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = Base64.decode(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

            signature.initVerify(pubKey);
            signature.update( content.getBytes(CHATSET) );

            boolean bverify = signature.verify( Base64.decode(sign) );
            return bverify;

        }catch (Exception e){
    
    
            log.error(e.getMessage(), e);
        }

        return false;
    }

    /**
     * RSA公钥加密
     * @param str 加密字符串
     * @param publicKey 公钥
     * @return 密文
     */
    public static String encryptByPublicKey( String str, String publicKey ) {
    
    

        try{
    
    

            //base64编码的公钥
            byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(publicKey);
            RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));

            //RSA加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            String outStr = org.apache.commons.codec.binary.Base64.encodeBase64String(cipher.doFinal(str.getBytes(CHATSET)));
            return outStr;

        }catch (Exception e) {
    
    
            log.error(e.getMessage(), e);
        }

        return null;
    }

    /**
     * RSA私钥解密
     * @param str 加密字符串
     * @param privateKey 私钥
     * @return 明文
     */
    public static String decryptByPrivateKey(String str, String privateKey){
    
    

        try{
    
    

            //64位解码加密后的字符串
            byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes(CHATSET));
            //base64编码的私钥
            byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));

            //RSA解密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            String outStr = new String(cipher.doFinal(inputByte));
            return outStr;

        }catch (Exception e) {
    
    
            log.error(e.getMessage(), e);
        }

        return null;
    }

}

resultado de la operación:

00:09:01.375 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - A发送给B的消息:{
    
    "sign":"X13XFI2khSarCOTDjENC/ZTtKfUKAPXuO3b7vossIvC6Aj9WMnKd9w/w64/EqTg+42SGvJXjVpvdglRMmWVrbFSWfmrEfjejaNcq35+aor6j4tMMq0ZVxRO4BxTe+qKDx/e0037dHACvAY2ecojVcbAQaECEc3TrZJguQnte/Nv0DZYPSv/9evPnuKL3DuTl/wy+JaTEhVrvsu/4jXpQ6HRbrhrC4dnzs6AZEqtBXvgfRSkq62jbAvUguDhhZ6yexA2/5S+oOqO8mgRVnooQxkAI5QZd9z0voDIrCDp4emKuznj7vMUjmOXgdD0C3l7LuBqQ469JmAD0U2fRLWMIiQ==","encryptMsg":"lFrlwDA4RjXaxrFPkd8DrbiWQ15o7nNzvLwdWUmTgkDyV5DGMXXsbcEP8aBWqmCje49ymAdzQl3MdO+U2t51QtTvzJOS55EBOZgonN8XJHKNiW7XikWbgf54vUx/mNdHH7fqpBM8AM1qcyH2N3OISFK4NP6eCKgMXRRb3hxw4oko3cGTa98Hnl8jlR9yR2Goy1euT7lpL04VqWcJtP0aEW5gurPkTEDRmOn1UC6x8qZX+K3dxrQfOQhJVRoIOb2hbu/HhzBsknJw1QZTS5IN/n0GlRiJQUwJllQUT4XRF6zmc2y4ewnLwlMY99WqwCaB4XFaBNQO9/5fa7A/XZTr7g=="}
00:09:01.378 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - -------------------------------------------------
00:09:01.378 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - B接收到A的消息:{
    
    "sign":"X13XFI2khSarCOTDjENC/ZTtKfUKAPXuO3b7vossIvC6Aj9WMnKd9w/w64/EqTg+42SGvJXjVpvdglRMmWVrbFSWfmrEfjejaNcq35+aor6j4tMMq0ZVxRO4BxTe+qKDx/e0037dHACvAY2ecojVcbAQaECEc3TrZJguQnte/Nv0DZYPSv/9evPnuKL3DuTl/wy+JaTEhVrvsu/4jXpQ6HRbrhrC4dnzs6AZEqtBXvgfRSkq62jbAvUguDhhZ6yexA2/5S+oOqO8mgRVnooQxkAI5QZd9z0voDIrCDp4emKuznj7vMUjmOXgdD0C3l7LuBqQ469JmAD0U2fRLWMIiQ==","encryptMsg":"lFrlwDA4RjXaxrFPkd8DrbiWQ15o7nNzvLwdWUmTgkDyV5DGMXXsbcEP8aBWqmCje49ymAdzQl3MdO+U2t51QtTvzJOS55EBOZgonN8XJHKNiW7XikWbgf54vUx/mNdHH7fqpBM8AM1qcyH2N3OISFK4NP6eCKgMXRRb3hxw4oko3cGTa98Hnl8jlR9yR2Goy1euT7lpL04VqWcJtP0aEW5gurPkTEDRmOn1UC6x8qZX+K3dxrQfOQhJVRoIOb2hbu/HhzBsknJw1QZTS5IN/n0GlRiJQUwJllQUT4XRF6zmc2y4ewnLwlMY99WqwCaB4XFaBNQO9/5fa7A/XZTr7g=="}
00:09:01.379 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - 验签通过,说明这个信息是B认可的用户发来的
00:09:01.386 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - 解密成功,说明这个信息就是发给B的
00:09:01.386 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - B收到的消息:你好

Siga la cuenta oficial e ingrese la palabra clave " java-summary " para obtener el código fuente.

Terminado, ¡llámalo un día!

[ Difusión de conocimientos, valor compartido ], gracias amigos por su atención y apoyo, soy [ Zhuge Xiaoyuan ], un trabajador migrante de Internet que está luchando en la vacilación. ! !

Supongo que te gusta

Origin blog.csdn.net/wuxiaolongah/article/details/108138772
Recomendado
Clasificación