java ecc 加密_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 classBcEcc {public static KeyPair initKeyPair(String algorithm, Integer keySize) throwsException {

Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());

KeyPairGenerator keyPairGenerator= KeyPairGenerator.getInstance("EC","BC");

keyPairGenerator.initialize(keySize,newSecureRandom());

KeyPair keyPair=keyPairGenerator.generateKeyPair();returnkeyPair;

}public static byte[] encrypt(byte[] content, PublicKey publicKey) throwsException {

Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());

Cipher cipher= Cipher.getInstance("ECIES","BC");//写不写 BC都可以,都是会选择BC实现来做

cipher.init(Cipher.ENCRYPT_MODE, publicKey);returncipher.doFinal(content);

}public static byte[] decrypt(byte[] content, PrivateKey privateKey) throwsException {

Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());

Cipher cipher= Cipher.getInstance("ECIES","BC");

cipher.init(Cipher.DECRYPT_MODE, privateKey);returncipher.doFinal(content);

}

}

二、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

签名示例

/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 支持 签名 验签 密钥交换//签名

functionecc_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-----\n' +privateKey+

'-----END EC PRIVATE KEY-----\n';return sign.sign(private_key).toString('base64');

}//验签

functionecc_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-----\n' +publicKey+'-----END PUBLIC KEY-----\n';

console.log(verify.verify(public_key, sign,"base64"));

}//密钥交换

functionecc_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

}

测试:

functionmain() {var algorithm = require("../main/ecc001crypto")//pkcs1

var priKey =

"MHQCAQEEID7ytsiAhdlS+hisEkdox7E2pTDP/nKmFdyKWyrqaFh/oAcGBSuBBAAKoUQDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==\n";//普通的后端key

var pubKey =

"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE0eb7o1ibninvBQlX8+sjigHaB4612Nn620p20zPxbKAjLa5w5M2jJwtD3v2bRDjmIeAV3AHhzxzPNt56t7B6A==\n";

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 库 支持 签名 验签 密钥交换 加密解密//签名 验签

functionecc_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");

});

});

}//密钥交换

functionecc_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加密解密

functionecc_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

}

测试:

functionmain() {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();

3.3、使用类库jsrsasign操作

//使用 eccrypto 库 支持 签名 验签 密钥交换 加密解密//签名 验签

functionecc_ecdsa_sign(signAlgorithmName, priKey, str) {var Jsrsasign = require('jsrsasign');//导入的Jsrsasign模块里面有很多实用的对象,对应不同的方法

console.log(Jsrsasign)

const privateKeyString= '-----BEGIN PRIVATE KEY-----\n' +priKey+ '\n-----END PRIVATE KEY-----\n';//传入私钥

//默认传入的私钥是PKCS#1的格式,所以采用readPrivateKeyFromPEMString(keyPEM)这个方法

//rsa.readPrivateKeyFromPEMString(PrivateKey);

//如果后台生产出来的私钥是PKCS#8的格式,就不能用readPrivateKeyFromPEMString(keyPEM)这个方法

const key =Jsrsasign.KEYUTIL.getKey(privateKeyString);//创建 Signature 对象,设置签名编码算法

const signature = newJsrsasign.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);

returnsign64;

}functionecc_ecdsa_verify(signAlgorithmName, pubKey, sign, str) {var Jsrsasign = require('jsrsasign');//导入的Jsrsasign模块里面有很多实用的对象,对应不同的方法

console.log(Jsrsasign)

const pKeyString= '-----BEGIN PUBLIC KEY-----\n' +pubKey+ '\n-----END PUBLIC KEY-----\n';//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 = newJsrsasign.KJUR.crypto.Signature({ alg: signAlgorithmName, prvkeypem: pKeyString });//传入待加密字符串

signature.updateString(str);var b =signature.verify(Jsrsasign.b64tohex(sign))//生成密文

console.log('sign verify =======', b);returnb;

}//ecc加密解密

functionecc_ecies() {var Jsrsasign = require('jsrsasign');var keypair = Jsrsasign.KEYUTIL.generateKeypair("EC","secp256k1");

console.log(keypair)var pubKey=keypair.pubKeyObj.pubKeyHexvar 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

}

测试

functionmain() {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的算法

方案二、使用工具类-jsrsasign

安装: npm i jsrsasign

参看3.2

3.5.3、java验签

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

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

@org.junit.Test

publicvoidpkcs8checkSign() 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络数据嗅探工具HexInject

网络数据嗅探工具HexInject网络数据嗅探是渗透测试工作的重要组成部分。通过嗅探,渗透人员可以了解足够多的内容。极端情况下,只要通过嗅探,就可以完成整个任务,如嗅探到支持网络登录的管理员帐号和密码。为了实现这个功能&#x…

.NET 云原生架构师训练营(权限系统 代码实现 ActionAccess)--学习笔记

▲ 点击上方“DotNet NB”关注公众号回复“1”获取开发者路线图学习分享 丨作者 / 郑 子 铭 这是DotNet NB 公众号的第188篇原创文章目录开发任务代码实现开发任务DotNetNB.Security.Core:定义 core,models,Istore;实现 defaul…

小米暑期实习在线笔试2015-04-25

周五晚上参加了小米的全国在线笔试,使用的是百一测评,不得不说,这是我参加过的最不靠谱的在线笔试。 先来描述题目,再来吐槽,在线笔试就是三个必做题和两个附加题。 必做题是三个算法题, 第一题是判断两个十…

表格列mouse经过时高亮显示

前几天Insus.NET有练习《表格行mouse经过时高亮显示》http://www.cnblogs.com/insus/p/3715733.html ,今天有奇想,是否可以实现mouse经过表的列时,整列高亮呢?Insus.NET就在前一示例中,修心jQuery来练习。 修改.mouseo…

REDIS调优

2019独角兽企业重金招聘Python工程师标准>>> 1、优先使用批量操作,例如hset, 2、批量命令用管道技术 3、因为redis是单线程的防止慢命令阻塞 4、可以搭建主从读写分离集群,费时的操作都移到读服务 用slowlog get 查看耗时操作 转载…

socket.io服务端是java_SpringBoot(23) 集成socket.io服务端和客户端实现通信

Slf4jService(value "socketIOService")public class SocketIOServiceImpl implements ISocketIOService {/*** 存放已连接的客户端*/private static Map clientMap new ConcurrentHashMap<>();/*** 自定义事件push_data_event,用于服务端与客户端通信*/priv…

LeetCode之Next Greater Element I

1、题目 You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1s elements in the corresponding places of nums2.The Next Greater Number of a number x in nums1 is …

分库分表下极致的优化

题外话这边说一句题外话,就是ShardingCore目前已经正式加入 NCC 开源组织了,也是希望框架和社区能发展的越来越好,希望为更多.netter提供解决方案和开源组件介绍依照惯例首先介绍本期主角:ShardingCore 一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案&#xff0c;…

网页小要求

1. 制作出的网页要求图文并茂&#xff0c;有自己设计的网站Logo图标&#xff1b;文字要有字体格式和颜色上的变化&#xff0c;图形要与网页的内容相关。2. 页面要求使用DIVCSS进行页面设计布局&#xff0c;至少 4个页面&#xff08;图像文件不能太大&#xff09;&…

关于photoshop

photoshop的常见快捷键&#xff1a;&#xff08;只写了一部分&#xff0c;还有的实用快捷键不知道&#xff09; 矩形、椭圆选框工具 M移动工具 V 套索、多边形套索、磁性套索 L 魔棒工具 W 裁剪工具 C 切片工具、切片选择工具 K 喷枪工具 J 画笔工具、铅笔工具 B 像皮图章、图案…

linux(centos) NET模式网络配置

2019独角兽企业重金招聘Python工程师标准>>> linux虚拟机一般使用桥接和net模式&#xff0c;但是由于桥接在不同的网络环境中&#xff0c;需要重新配置&#xff0c;所以建议使用net模式&#xff0c;net模式的配置步骤如下&#xff1a; 虚拟机网络连接使用NAT模式&am…

LeetCode之Island Perimeter

1、题目 You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one is…

java获取tomcat目录结构_tomcat目录结构简介_动力节点Java学院整理

tomcat目录结构简介如果我们有一个web应用&#xff0c;名称为“mail”(同时也是web应用所在目录的名称)&#xff0c;那么其目录内不同类型的文件应该服从如下放置的规则&#xff1a;一般来讲&#xff1a;对于html、jsp、css、js文件等&#xff0c;可以直接放置在web应用所在目录…

Linux和Windows下部署BeetleX服务网关

有朋友希望写一篇BeetleX服务网关部署到Linux和windows下并以服务的方式运行的介绍文章。接下详细介绍如何做并简单介绍一下网的使用。首先需要在官网(beetlex-io.com)下载对应版本的BeetleX服务网关&#xff08;现阶段只支持linux64和windows64&#xff09;&#xff0c;下载完…

HDU 1978 How many ways DP问题

How many ways Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2568 Accepted Submission(s): 1509 Problem Description这是一个简单的生存游戏&#xff0c;你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的…

课堂练习-找水王绪

题目&#xff1a;三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水&#xff0c;传说在论坛上有一个“水王”&#xff0c;他不但喜欢发帖&#xff0c;还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子数目的一半。 如果你有一张当前论坛的…

LeetCode之Nim Game

1、题目 You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove …

适配器模式和装饰模式

1 什么是适配器模式 当我要使用一个类时&#xff0c;但是我发现它的接口不是我想要的模样&#xff0c;这个时候&#xff0c;我可以使用适配器模式&#xff0c;新设计一个类&#xff0c;然后这个类提供我想要的接口&#xff0c;在它里面引用原来的类。 2 什么是装饰模式 当我想要…

java添加事件监听器_Java事件监听器的四种实现方式

自身类作为事件监听器外部类作为事件监听器匿名内部类作为事件监听器内部类作为事件监听器自身类作为事件监听器:1 import javax.swing.*;2 import java.awt.*;3 import java.awt.event.*;45 /**6 *Java事件处理机制:自身类作为事件监听器7 *authorWinty(wintysgmail.com)8 *ve…

使用Brighter实现轻量型独立管道

前言上次&#xff0c;我们介绍了使用MediatR的Behaviors功能&#xff0c;在业务层实现管道模式。(《为什么应该在业务层实现管道模式&#xff0c;而不用ASP.NET Core Middleware实现 | 2点原因和实现方式》)但是&#xff0c;这种管道有个特点或者说缺点&#xff0c;不管你需不需…