java js 认证,jsrsasign 前台签名,Java后台验证前台签名

rsa  具体是什么  这个就不在多说。算法实现啊应用啊 已经有很多了。今天记录下 这种特殊的需求,前台签名,后台验证

Java后台产生 密匙对

pom.xml 添加BC 依赖

org.bouncycastle

bcprov-jdk15on

1.51

RSATools

package com.oscgc.securevideo.server.tool.rsa;

import java.io.IOException;

import java.io.StringWriter;

import java.security.*;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

import org.bouncycastle.openssl.PEMWriter;

import org.bouncycastle.util.io.pem.PemObject;

/**

* Created by Yq on 2015/6/10.

*/

public class RsaKeyTools {

public static final String PEM_PUBLICKEY = "PUBLIC KEY";

public static final String PEM_PRIVATEKEY = "PRIVATE KEY";

/**

* generateRSAKeyPair

*

* @param keySize

* @return

*/

public static KeyPair generateRSAKeyPair(int keySize) {

KeyPairGenerator generator = null;

SecureRandom random = new SecureRandom();

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

try {

generator = KeyPairGenerator.getInstance("RSA", "BC");

}

catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

catch (NoSuchProviderException e) {

e.printStackTrace();

}

generator.initialize(keySize, random);

KeyPair keyPair = generator.generateKeyPair();

return keyPair;

}

/**

* convertToPemKey

*

* @param publicKey

* @param privateKey

* @return

*/

public static String convertToPemKey(RSAPublicKey publicKey,

RSAPrivateKey privateKey) {

if (publicKey == null && privateKey == null) {

return null;

}

StringWriter stringWriter = new StringWriter();

try {

PEMWriter pemWriter = new PEMWriter(stringWriter, "BC");

if (publicKey != null) {

pemWriter.writeObject(new PemObject(PEM_PUBLICKEY,

publicKey.getEncoded()));

}

else {          //此处产生的privatekey 的格式是 PKCS#8 的格式

pemWriter.writeObject(new PemObject(PEM_PRIVATEKEY,

privateKey.getEncoded()));

}

pemWriter.flush();

}

catch (IOException e) {

e.printStackTrace();

}

return stringWriter.toString();

}

public static byte[] sign(String data, byte[] privateKey) throws Exception {

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

Signature signature = Signature.getInstance("SHA1WithRSA");

signature.initSign(privateKey2);

signature.update(data.getBytes());

return signature.sign();

}

//后台测试签名的时候 要和前台保持一致,所以需要将结果转换

private static String bytes2String(byte[] bytes) {

StringBuilder string = new StringBuilder();

for (byte b : bytes) {

String hexString = Integer.toHexString(0x00FF & b);

string.append(hexString.length() == 1 ? "0" + hexString : hexString);

}

return string.toString();

}

public static boolean verify(String data,

byte[] publicKey,

byte[] signatureResult) {

try {

X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

Signature signature = Signature.getInstance("SHA1WithRSA");

signature.initVerify(publicKey2);

signature.update(data.getBytes());

return signature.verify(signatureResult);

}

catch (Exception e) {

e.printStackTrace();

}

return false;

}

//前台的签名结果是将byte 中的一些 负数转换成了正数, //但是后台验证的方法需要的又必须是转换之前的

public static byte[] hexStringToByteArray(String data) {

int k = 0;

byte[] results = new byte[data.length() / 2];

for (int i = 0; i + 1 < data.length(); i += 2, k++) {

results[k] = (byte) (Character.digit(data.charAt(i), 16) << 4);

results[k] += (byte) (Character.digit(data.charAt(i + 1), 16));

}

return results;

}

public static void main(String[] args) {

String str = "coder";

KeyPair k = generateRSAKeyPair(1024);

String publicKey = convertToPemKey((RSAPublicKey) k.getPublic(), null);

String privateKey = convertToPemKey(null,

(RSAPrivateKey) k.getPrivate());

System.out.println("publicKey__\n" + publicKey);

System.out.println("privateKey_\n" + privateKey);

try {

byte[] signautreResult = sign(str, k.getPrivate().getEncoded());

String signatureStr = bytes2String(signautreResult);

byte[] signatureResult2 = hexStringToByteArray(signatureStr);

boolean b = verify(str,

k.getPublic().getEncoded(),

signatureResult2);

System.out.print("iii " + b);

}

catch (Exception e) {

e.printStackTrace();

}

}

}

Javascript    签名用到的lib 是 jsrsasign  包含:

更多的详细  github 地址:https://kjur.github.io/jsrsasign/

在官网给定的签名例子代码如下:

function doSign() {

var rsa = new RSAKey();

rsa.readPrivateKeyFromPEMString(document.form1.prvkey1.value);

var hashAlg = document.form1.hashalg.value;

var hSig = rsa.signString(document.form1.msgsigned.value, hashAlg);

document.form1.siggenerated.value = linebrk(hSig, 64);

}

这里我们需要改动一下:

rsa.readPrivateKeyFromPEMString(document.form1.prvkey1.value);官方api 中对这个方法有这样的说明:

readPrivateKeyFromPEMString(keyPEM)

read PKCS#1 private key from a string

这个方法传入的privatekey 是需要 PKCS#1 格式的,但是后台 产生出来的private key 是PKCS#8的格式的,这里就不能用这个方法,签名会通不过。

查看jsrsasign 的 api

KEYUTIL - loading RSA/EC/DSA private/public key from PEM formatted PKCS#1/5/8 and X.509 certificate

因此 js  生成RSAkey  对象

rsa=KEYUTIL.getKey(document.form1.prvkey1.value);

这个方法支持PKCS#8 pem 格式的privatekey  可以通过签名。

ce930c475d97934c6ad8a1e18e900f60.png

来源:https://www.cnblogs.com/yqweber/p/4583140.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值