zoukankan      html  css  js  c++  java
  • java-信息安全(十一)-非对称加密算法002-ECC,签名003-ECDSA签名

    一、概述

      ECC算法(Elliptic curve cryptography,椭圆曲线密码学

      椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。

      是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。在软件注册保护方面起到很大的作用,一般的序列号通常由该算法产生。

    • ECDSA is a digital signature algorithm是一种数字签名算法
    • ECIES is an Integrated Encryption scheme 是一种集成加密方案
    • ECDH is a key secure key exchange algorithm是密钥安全密钥交换算法

    1.1、jdk实现

      ECC算法在jdk1.5后加入支持,目前仅仅只能完成密钥的生成与解析。 

      JDK1.7开始内置了ECC公私钥生成、签名验签,但没有实现加密解密。

    jdk支持ecdsa、不支持ecdh、ecies

    bc支持ecdsa、ecdh、ecies

    1.2、bc实现【提供实现】

      在Java中使用ECC算法有以下几点需要注意:

    • JDK1.7开始内置了ECC公私钥生成、签名验签,但没有实现加密解密,因此需要使用BouncyCastle来做Security Provider;
    • 在Java中使用高级别的加解密算法,比如AES使用256bit密钥、ECC使用Secp256r1等需要更新JRE的security policy文件,否则会报类似“Illegal key size or default parameters”这样的错误。具体怎样更换policy文件,可以参考这里
    • 实际项目开发过程中,可能发现有传递给Java的公钥不是完整的X.509 SubjectPublicKeyInfo,比如只传递了一个65字节的ECPoint过来,这种情况可以跟对方沟通清楚所使用的Algorithm以及NamedCurve,补全DER数据后,再使用Java Security库解析。
    public class BcEcc {
        public static KeyPair initKeyPair(String algorithm, Integer keySize) throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC","BC");
            keyPairGenerator.initialize(keySize, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            return keyPair;
        }
    
        public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("ECIES","BC");//写不写 BC都可以,都是会选择BC实现来做
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return cipher.doFinal(content);
        }
    
        public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("ECIES","BC");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return cipher.doFinal(content);
        }
    }

    代码地址:https://github.com/bjlhx15/algorithm-sign.git

    二、ECDSA签名

    基于ECC与DSA签名算法分类信息,ECDSA(elliptic curve digital signature algorithm) 椭圆曲线数字签名算法:速度快,强度高,签名短

    算法 密钥长度 默认长度 签名长度 实现的方
    NONEwithECDSA 112-571 256 128 JDK/BC
    RIPEMD160withECDSA 同上 256 160 BC
    SHA1withECDSA ... 256 160 JDK/BC
    SHA224withECDSA ... 256 224 JDK/BC
    SHA256withECDSA ... 256 256 JDK/BC
    SHA384withECDSA ... 256 384 JDK/BC
    SHA512withECDSA ... 256 512 JDK/BC

    签名示例

      代码地址:https://github.com/bjlhx15/algorithm-sign.git

        /algorithm-sign/algorithm-sign-impl/src/main/java/com/github/bjlhx15/security/sign003ecc 

    http://baike.baidu.com/item/%E6%A4%AD%E5%9C%86%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/10305582?sefr=cr

    三、nodejs版

    crypto支持ecdsa、ecdh,不支持ecies加密解密

    ecccrypto支持ecies加密解密

    jsrsasign 使用

    3.1、使用原生crypto 操作ecdsa、ecdh

    无需安装类库模块

    // 原生crypto 支持 签名 验签  密钥交换
    //签名
    function ecc_ecdsa_sign(signAlgorithmName, privateKey, srcData) {
        const crypto = require('crypto');
    
        const sign = crypto.createSign(signAlgorithmName);
    
        sign.update(srcData);
    
        // 注意这里是pkcs1, java后端默认是pkcs8
        const private_key = '-----BEGIN EC PRIVATE KEY-----
    ' +
            privateKey +
            '-----END EC PRIVATE KEY-----
    ';
        return sign.sign(private_key).toString('base64');
    }
    
    //验签
    function ecc_ecdsa_verify(signAlgorithmName, publicKey,sign, srcData) {
    
        // 校验这里直接使用公钥,直接后端java生成的即可
        const crypto = require('crypto');
        const verify = crypto.createVerify(signAlgorithmName);
        verify.update(srcData);
        // verify.update(new Buffer(srcData, 'utf-8'));
        var public_key='-----BEGIN PUBLIC KEY-----
    ' +
        publicKey
        +'-----END PUBLIC KEY-----
    ';
    
        console.log(verify.verify(public_key, sign,"base64"));
    }
    
    //密钥交换
    function ecc_ecdh(srcData) {
        const crypto = require('crypto');
        const assert = require('assert');
        // Generate Alice's keys...
        const alice = crypto.createECDH('secp521r1');
        const alice_key = alice.generateKeys();
        // Generate Bob's keys...
        const bob = crypto.createECDH('secp521r1');
        const bob_key = bob.generateKeys();
        // Exchange and generate the secret...
        const alice_secret = alice.computeSecret(bob_key);
        const bob_secret = bob.computeSecret(alice_key);
        console.log("alice_secret:" + alice_secret.toString("base64"))
        console.log("bob_secret:" + bob_secret.toString("base64"))
        assert(alice_secret, bob_secret);
    }
    
    //算法
    var algorithmName = {
        sha1: "sha1",
        sha224: "sha224",
        sha256: "sha256",
        sha384: "sha384",
        sha512: "sha512"
    }
    
    module.exports = {
        algorithmName, ecc_ecdsa_sign, ecc_ecdsa_verify, ecc_ecdh
    }

    测试:

    function main() {
        var algorithm = require("../main/ecc001crypto")
        //pkcs1
        var priKey =
            "MHQCAQEEID7ytsiAhdlS+hisEkdox7E2pTDP/nKmFdyKWyrqaFh/oAcGBSuBBAAKoUQDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==
    ";
        //普通的后端key
        var pubKey =
            "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==
    ";
    
    
        console.log("-----签名-验签-------")
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.sha1, priKey, "hello world")
        console.log(value)
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha1, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.sha224, priKey, "hello world")
        console.log(value)
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha224, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.sha256, priKey, "hello world")
        console.log(value)
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha256, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.sha384, priKey, "hello world")
        console.log(value)
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha384, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.sha512, priKey, "hello world")
        console.log(value)
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha512, pubKey, value, "hello world")
    
        console.log("-----java的签名-验签-------")
        var javaSign='MEYCIQDFtnUYxR0jPw8/16iZxYlEkW+AJkcPIxpXSWNnU9DoGwIhAJ1A8XlSoeqRvGC9ZzOthvGvQoOXZ+saiy7iryHINJa0';
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha256, pubKey, javaSign, "我是测试数据对的纷纷")
    
        console.log("-----密钥交换-------")
        algorithm.ecc_ecdh("")
    }
    
    
    main();

    3.2、使用类库ecccrypto操作ecdsa、ecdh、ecies加密解密

    安装:npm i eccrypto

    // 使用 eccrypto 库 支持 签名 验签  密钥交换   加密解密
    //签名 验签
    function ecc_ecdsa(signAlgorithmName, pubKey, priKey, str) {
        var crypto = require("crypto");
        var eccrypto = require("eccrypto");
    
        // A new random 32-byte private key.
        var privateKey = eccrypto.generatePrivate();
        console.log(privateKey.toString("base64"))
        // Corresponding uncompressed (65-byte) public key.
        var publicKey = eccrypto.getPublic(privateKey);
        console.log(publicKey.toString("base64"))
        // var str = "message to sign";
        // Always hash you message to sign!
        var msg = crypto.createHash(signAlgorithmName).update(str).digest();
    
        eccrypto.sign(privateKey, msg).then(function (sig) {
            console.log("Signature in DER format:", sig.toString("base64"));
            eccrypto.verify(publicKey, msg, sig).then(function () {
                console.log("Signature is OK");
            }).catch(function () {
                console.log("Signature is BAD");
            });
        });
    }
    
    //密钥交换
    function ecc_ecdh() {
        var eccrypto = require("eccrypto");
    
        var privateKeyA = eccrypto.generatePrivate();
        var publicKeyA = eccrypto.getPublic(privateKeyA);
        var privateKeyB = eccrypto.generatePrivate();
        var publicKeyB = eccrypto.getPublic(privateKeyB);
    
        eccrypto.derive(privateKeyA, publicKeyB).then(function (sharedKey1) {
            eccrypto.derive(privateKeyB, publicKeyA).then(function (sharedKey2) {
                console.log("Both shared keys are equal:", sharedKey1.toString("base64"), sharedKey2.toString("base64"));
            });
        });
    }
    
    //ecc加密解密
    function ecc_ecies() {
        var eccrypto = require("eccrypto");
    
        var privateKeyA = eccrypto.generatePrivate();
        var publicKeyA = eccrypto.getPublic(privateKeyA);
        var privateKeyB = eccrypto.generatePrivate();
        var publicKeyB = eccrypto.getPublic(privateKeyB);
    
        // Encrypting the message for B.
        eccrypto.encrypt(publicKeyB, Buffer.from("msg to b")).then(function (encrypted) {
            // B decrypting the message.
            console.log("Message to part B[encrypted]:", encrypted.ciphertext.toString("base64"));
            eccrypto.decrypt(privateKeyB, encrypted).then(function (plaintext) {
                console.log("Message to part B:", plaintext.toString());
            });
        });
    
        // Encrypting the message for A.
        eccrypto.encrypt(publicKeyA, Buffer.from("msg to a")).then(function (encrypted) {
            // A decrypting the message.
            console.log("Message to part A[encrypted]:", encrypted.ciphertext.toString("base64"));
            eccrypto.decrypt(privateKeyA, encrypted).then(function (plaintext) {
                console.log("Message to part A:", plaintext.toString());
            });
        });
    }
    
    //算法
    var algorithmName = {
        sha1: "sha1",
        sha224: "sha224",
        sha256: "sha256",
        // sha384: "sha384",  //Error: Message is too long
        // sha512: "sha512"
    }
    
    module.exports = {
        algorithmName, ecc_ecdsa, ecc_ecdh, ecc_ecies
    }

    测试:

    function main() {
        var algorithm = require("../main/ecc002eccrypto") 
        //pkcs1
        var priKey =
            "MHQCAQEEID7ytsiAhdlS+hisEkdox7E2pTDP/nKmFdyKWyrqaFh/oAcGBSuBBAAKoUQDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==";
        //普通的后端key
        var pubKey =
            "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==";
    
    
        console.log("-----签名-验签-------")
    
        var value = algorithm.ecc_ecdsa(algorithm.algorithmName.sha1, pubKey,priKey, "hello world")
        var value = algorithm.ecc_ecdsa(algorithm.algorithmName.sha224, pubKey,priKey, "hello world")
        var value = algorithm.ecc_ecdsa(algorithm.algorithmName.sha256, pubKey,priKey, "hello world")
        // var value = algorithm.ecc_ecdsa(algorithm.algorithmName.sha384, pubKey,priKey, "hello world")
       
        console.log("-----密钥交换-------")
        algorithm.ecc_ecdh("")
        console.log("-----加密 解密-------")
        algorithm.ecc_ecies("")
    }
    
    
    main();

    更多:https://www.npmjs.com/package/eccrypto

    3.3、使用类库jsrsasign操作

    // 使用 eccrypto 库 支持 签名 验签  密钥交换   加密解密
    //签名 验签
    function ecc_ecdsa_sign(signAlgorithmName, priKey, str) {
        var Jsrsasign = require('jsrsasign');
        // 导入的Jsrsasign模块里面有很多实用的对象,对应不同的方法
        console.log(Jsrsasign)
    
        const privateKeyString = '-----BEGIN PRIVATE KEY-----
    ' +
            priKey + '
    -----END PRIVATE KEY-----
    ';
    
        // 传入私钥
        // 默认传入的私钥是PKCS#1的格式,所以采用readPrivateKeyFromPEMString(keyPEM)这个方法
        // rsa.readPrivateKeyFromPEMString(PrivateKey);
        // 如果后台生产出来的私钥是PKCS#8的格式,就不能用readPrivateKeyFromPEMString(keyPEM)这个方法
        const key = Jsrsasign.KEYUTIL.getKey(privateKeyString);
        // 创建 Signature 对象,设置签名编码算法
        const signature = new Jsrsasign.KJUR.crypto.Signature({ alg: signAlgorithmName });
        // 初始化
        signature.init(key);
        // 上面3行相当于这句
        // const signature = new Jsrsasign.KJUR.crypto.Signature({ alg: signAlgorithmName,prvkeypem:privateKeyString });//!这里指定 私钥 pem!
    
        // 传入待加密字符串
        signature.updateString(str);
        // 生成密文
        const originSign = signature.sign();
        const sign64 = Jsrsasign.hextob64(originSign);
        console.log('sign base64 =======', sign64);
        // const sign64u = Jsrsasign.hextob64u(originSign);
        // console.log('sign base64u=======', sign64u);
        return sign64;
    }
    
    function ecc_ecdsa_verify(signAlgorithmName, pubKey, sign, str) {
        var Jsrsasign = require('jsrsasign');
        // 导入的Jsrsasign模块里面有很多实用的对象,对应不同的方法
        console.log(Jsrsasign)
    
        const pKeyString = '-----BEGIN PUBLIC KEY-----
    ' +
            pubKey + '
    -----END PUBLIC KEY-----
    ';
    
        // 1.传入私钥
        // 默认传入的私钥是PKCS#1的格式,所以采用readPrivateKeyFromPEMString(keyPEM)这个方法
        // rsa.readPrivateKeyFromPEMString(PrivateKey);
        // 如果后台生产出来的私钥是PKCS#8的格式,就不能用readPrivateKeyFromPEMString(keyPEM)这个方法
        // const key = Jsrsasign.KEYUTIL.getKey(pKeyString);
        //2. 创建 Signature 对象,设置签名编码算法
        // const signature = new Jsrsasign.KJUR.crypto.Signature({ alg: signAlgorithmName});
        //3.初始化
        //signature.init(key)
        //上面3行另一种写法
        const signature = new Jsrsasign.KJUR.crypto.Signature({ alg: signAlgorithmName, prvkeypem: pKeyString });
        // 传入待加密字符串
        signature.updateString(str);
        var b = signature.verify(Jsrsasign.b64tohex(sign))
        // 生成密文
        console.log('sign verify =======', b);
        return b;
    }
    
    //ecc加密解密
    function ecc_ecies() {
        var Jsrsasign = require('jsrsasign');
        var keypair = Jsrsasign.KEYUTIL.generateKeypair("EC","secp256k1");
        console.log(keypair)
        var pubKey=keypair.pubKeyObj.pubKeyHex
        var priKey=keypair.prvKeyObj.prvKeyHex
        console.log(Jsrsasign.hextob64(pubKey))
        console.log(Jsrsasign.hextob64(priKey))
        
    
    }
    
    //算法
    var algorithmName = {
        SHA1withECDSA: "SHA1withECDSA",
        SHA224withECDSA: "SHA224withECDSA",
        SHA256withECDSA: "SHA256withECDSA",
        SHA384withECDSA: "SHA384withECDSA",  //Error: Message is too long
        SHA512withECDSA: "SHA512withECDSA"
    }
    
    module.exports = {
        algorithmName, ecc_ecdsa_sign, ecc_ecdsa_verify, ecc_ecies
    }

    测试

    function main() {
        var algorithm = require("../main/ecc003jsrsasign")
        //pkcs1
        var priKeyPkcs1 =
            "MHQCAQEEID7ytsiAhdlS+hisEkdox7E2pTDP/nKmFdyKWyrqaFh/oAcGBSuBBAAKoUQDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==";
        var priKeyPkcs8 =
            "MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQgPvK2yICF2VL6GKwSR2jHsTalMM/+cqYV3IpbKupoWH+gBwYFK4EEAAqhRANCAAQTR5vujWJueKe8FCVfz6yOKAdoHjrXY2frbSnbTM/FsoCMtrnDkzaMnC0Pe/ZtEOOYh4BXcAeHPHM823nq3sHo";
     
        //普通的后端key
        var pubKey =
            "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==";
    
        console.log("-----签名-验签-------")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.SHA1withECDSA, priKeyPkcs8, "hello world")
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.SHA1withECDSA, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.SHA224withECDSA, priKeyPkcs8, "hello world")
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.SHA224withECDSA, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.SHA256withECDSA, priKeyPkcs8, "hello world")
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.SHA256withECDSA, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.SHA384withECDSA, priKeyPkcs8, "hello world")
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.SHA384withECDSA, pubKey, value, "hello world")
    
        var value = algorithm.ecc_ecdsa_sign(algorithm.algorithmName.SHA512withECDSA, priKeyPkcs8, "hello world")
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.SHA512withECDSA, pubKey, value, "hello world")
    
        // console.log("-----密钥交换-------")
        // algorithm.ecc_ecdh("")
        console.log("-----加密 解密-------")
        algorithm.ecc_ecies("")
    }
    
    
    main();

    更多:https://github.com/kjur/jsrsasign.git

    3.5、nodejs结合java使用签名验签

    Java 语言,就使用「PKCS8」密钥格式,也叫 「PKCS#8」,如果非 Java 语言可以考虑「PKCS1」。

    Java 使用private key 和 public key时,要把首尾「-----BEGIN PRIVATE KEY-----」之类的删除,但在 JavaScript 里使用时,一定要加上。

    nodejs与java的ecc加密签名通讯。

    3.5.1、使用java操作生成双方公私钥

    java端ecc:https://github.com/bjlhx15/algorithm-sign.git

    使用测代码生成:com.github.bjlhx15.security.encryptSign001BcEcc.BcEccAlgorithmUtilTest 生成  initKeyPairBase64  ,后续操作方便使用 process 测试

    A pubKey:MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYfNJOtj1Xkfp9bVqoXlB4ixVhNtN7Zl+mPPiyeDrPbKNX7XhmN8EcyOhjfpbXYmJY8JItue9rajOqouS45wYpQ==
    A priKey:MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQg1xRtgNwZ3oo+509hN+EkoH+hGRDhHiq0zfZy0zQxAOegBwYFK4EEAAqhRANCAARh80k62PVeR+n1tWqheUHiLFWE203tmX6Y8+LJ4Os9so1fteGY3wRzI6GN+ltdiYljwki2572tqM6qi5LjnBil
    A priKey[pkcs1]:MHQCAQEEINcUbYDcGd6KPudPYTfhJKB/oRkQ4R4qtM32ctM0MQDnoAcGBSuBBAAKoUQDQgAEYfNJOtj1Xkfp9bVqoXlB4ixVhNtN7Zl+mPPiyeDrPbKNX7XhmN8EcyOhjfpbXYmJY8JItue9rajOqouS45wYpQ==
    
    B pubKey:MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJN5FVWR90XaFSMjVEbCGgAqrMbvHCIM0i84kVLuKpESDNgGSnz0AZt4HKElRR8MkZbzsnJdMq5gmDxTrYMyg8Q==
    B priKey:MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQgUHzI83yRMCfl395xdpx/CB2eZPIsEORBN3OPQyN0RT6gBwYFK4EEAAqhRANCAAQk3kVVZH3RdoVIyNURsIaACqsxu8cIgzSLziRUu4qkRIM2AZKfPQBm3gcoSVFHwyRlvOycl0yrmCYPFOtgzKDx
    
    A 向 B 发送数据【密文、签名】
    A 需要用B的 公钥加密数据
    密文:BNmsoiMfajCwsqvNGwx198QliMzFVFySnsGkJuBWGNHxbe/lKxcsDnh3qTyD8DNd+m0se2l3mmJudy+2+msDwCde2lVGLDCRjHh8htCFaFJUGSPP/f7IrzWUMJB1zF8nr1VB7GIGgMeGyGaynE31viTg3Q==
    A 需要用自己的 私钥签名
    sign:MEUCIQCEF3hAZed32ZLwxuhuGozogPstm2YPSYNp+jMqGTnK7wIge3L+RMWegt9eBm6u5j7oWi06boKTWspOBSWJRY33Fj8=
    A 向 B 发送数据:ok
    
    B用 需要用自己 的私钥解密
    解密后:我是测试数据对的纷纷
    B需要用A  的公钥验签
    check:true

    3.5.2、nodejs交互操作

    方案一、使用nodejs自带模块crypto签名

    将A的公私钥,分发给nodejs使用

    java使用的是pkcs8,nodejs的crypto使用的是pkcs1,所以这里使用的是 priKey[pkcs1]

    参看3.1示例,注意使用的是sha256的算法

    签名值:MEUCIEuuqtMhHw/JvZgyBrs5djPD0VIZjxdeHYUWeEJsqcdlAiEAyVowkbpvQJuZWrUG2FXhq6+BFDpq9wFSl2CcjcSjGRM=

    方案二、使用工具类-jsrsasign

    安装: npm i jsrsasign
    参看3.2

    3.5.3、java验签

    此时nodejs端会将签名发送至,java端

    java端验签:使用客户的公钥,以及签名

        @org.junit.Test
        public void pkcs8checkSign() throws Exception {
            String msg = "我是测试数据对的 http://blog.bjlhx.top/";
    
            System.out.println("B需要用A  的公钥验签");
            boolean check = BcEccAlgorithmUtil.verify("MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYfNJOtj1Xkfp9bVqoXlB4ixVhNtN7Zl+mPPiyeDrPbKNX7XhmN8EcyOhjfpbXYmJY8JItue9rajOqouS45wYpQ==",
                    msg,
                    "MEUCIEuuqtMhHw/JvZgyBrs5djPD0VIZjxdeHYUWeEJsqcdlAiEAyVowkbpvQJuZWrUG2FXhq6+BFDpq9wFSl2CcjcSjGRM=");
            System.out.println("check:" + check);
        }

    输出

    B需要用A  的公钥验签
    check:true

    https://github.com/bjlhx15/algorithm-sign.git的encryptSign001BcEcc 的pkcs8checkSign

    3.5.4、java端回发数据签名

    参看:com.github.bjlhx15.security.encryptSign001BcEcc.BcEccAlgorithmUtilTest#process

    签名值:MEQCIEQbw0cfSMncVG/3OT+/HnNQamNAZFPLYt5uYpjCsvoZAiAI9l4hdDDJqXlfKBxovkBUtqjl8r+5BQHZfkS4QRH0/A==

    3.5.5、node验签

    参看3.1

        console.log("-----java的签名-验签-------")
        var javaSign = 'MEQCIEQbw0cfSMncVG/3OT+/HnNQamNAZFPLYt5uYpjCsvoZAiAI9l4hdDDJqXlfKBxovkBUtqjl8r+5BQHZfkS4QRH0/A==';
        algorithm.ecc_ecdsa_verify(algorithm.algorithmName.sha256, pubKeyRemote, javaSign, msg+":B")

    pubKeyRemote:是B的公钥;

    java端代码:https://github.com/bjlhx15/algorithm-sign.git的com.github.bjlhx15.security.encryptSign001BcEcc.BcEccAlgorithmUtilTest

    nodejs端代码:https://github.com/bjlhx15/algorithm-sign-nodejs.git 的ecc00X代码 主要看:testEcc001crypto

  • 相关阅读:
    古代军队的官的从大到小的排序
    [转]DAO、RDO、ADO、OLE DB 、ODBC and JDB
    JSP页面之间参数传递中文出现乱码
    重置VS2008插件环境
    PB7中调用VC6的DLL
    Visual Studio统计有效代码行数
    php.ini 中文版
    IDEA Plugin JB* Components
    [转]你还在为怎么查看字节码指令而担忧吗?
    战地2, 2142解决Win10运行闪退问题
  • 原文地址:https://www.cnblogs.com/bjlhx/p/6564817.html
Copyright © 2011-2022 走看看