我是靠谱客的博主 传统人生,最近开发中收集的这篇文章主要介绍通过Rsa加密验证。,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

密钥验证的流程如下:

    假如我们需要做一个服务,让用户通过密钥验证的方式来访问服务内容。客户端通过调用服务端程序生成密钥并返回客户端,并再次传入验证密钥到服务段进行密钥验证。客户端这边通过用户名密码和密钥申请时间等字段共同生成密钥,密钥相关代码如下:

                

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

public class RSAUtils {
private static final String SIGN_ALGORITHMS = "SHA256withRSA";

private static final String OLD_SIGN_ALGORITHMS = "SHA1withRSA";

private static final Map<String, PrivateKey> PRIVATEKEY_CACHE = new ConcurrentHashMap<>();

private static final Map<String, PublicKey> PUBLICKEY_CACHE = new ConcurrentHashMap<>();


private static InputStream getResourceAsStream(String resource) throws IOException {
InputStream in = null;

ClassLoader loader = RSAUtils.class.getClassLoader();

if (loader != null) {
in = loader.getResourceAsStream(resource);

}
if (in == null) {
in = ClassLoader.getSystemResourceAsStream(resource);

}
if (in == null) {
throw new IOException("请将密钥文件" + resource + "放到工程classpath目录!");

}
return in;

}
public static PrivateKey getPrivateKey(String key) {
if (PRIVATEKEY_CACHE.containsKey(key)) {
return PRIVATEKEY_CACHE.get(key);

}
PrivateKey privateKey = null;

try {
InputStream in = getResourceAsStream(key);

if (in == null) {
return null;

}
byte[] keyBytes = IOUtils.toByteArray(in);

IOUtils.closeQuietly(in);

privateKey = bytesToPrivateKey(keyBytes);

PRIVATEKEY_CACHE.put(key, privateKey);

} catch (Exception e) {
e.printStackTrace();

}
return privateKey;

}
public static PublicKey getPublicKey(String key) {
if (PUBLICKEY_CACHE.containsKey(key)) {
return PUBLICKEY_CACHE.get(key);

}
PublicKey publicKey = null;

try {
InputStream in = getResourceAsStream(key);

if (in == null) {
return null;

}
byte[] keyBytes = IOUtils.toByteArray(in);

IOUtils.closeQuietly(in);

publicKey = bytesToPublicKey(keyBytes);

PUBLICKEY_CACHE.put(key, publicKey);

} catch (Exception e) {
e.printStackTrace();

}
return publicKey;

}
/**

* * 生成密钥对 *

*

* @return KeyPair *

* @throws Exception

*/

public static KeyPair generateKeyPair() throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

// 没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低

final int keySize = 2048;

keyPairGen.initialize(keySize, new SecureRandom());

return keyPairGen.generateKeyPair();

} catch (Exception e) {
throw new Exception(e.getMessage());

}
}
/***

*
使用私钥对数据签名

* @param content 待签名数据

* @param privateKey 私钥

* @return 签名数据

*/

public static String sign(String content, PrivateKey privateKey) {
try {
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

signature.initSign(privateKey);

signature.update(content.getBytes("UTF-8"));

byte[] signed = signature.sign();

return Base64.getEncoder().encodeToString(signed);

} catch (Exception e) {
e.printStackTrace();

}
return null;

}
/**

* 使用公钥对签名数据进行验证

*

* @param content
待签名数据

* @param sign
签名数据

* @param publicKey 公钥

* @return 验证结果

*/

public static boolean verify(String content, String sign, PublicKey publicKey) {
try {
if (Pattern.matches("^[0-9a-f]+$", sign)) {
Signature signature = Signature.getInstance(OLD_SIGN_ALGORITHMS);

signature.initVerify(publicKey);

signature.update(content.getBytes("UTF-8"));

return signature.verify(Hex.decodeHex(sign.toCharArray()));

} else {
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);

signature.initVerify(publicKey);

signature.update(content.getBytes("UTF-8"));

return signature.verify(Base64.getDecoder().decode(sign));

}
} catch (Exception e) {
e.printStackTrace();

}
return false;

}
/**

* 将公钥/私钥转为base64格式密钥串

*

* @param key

* @return

* @throws IOException

*/

public static String keyToString(Key key) {
byte[] keyBytes = key.getEncoded();

return Base64.getEncoder().encodeToString(keyBytes);

}
/**

* 将公钥/私钥转为base64格式密钥byte数组

*

* @param key

* @return

* @throws IOException

*/

public static byte[] keyToBytes(Key key) {
byte[] keyBytes = key.getEncoded();

return Base64.getEncoder().encode(keyBytes);

}
/**

* 将pkcs8 base64 的byte数组转为私钥

*

* @param bytes

* @return

* @throws InvalidKeySpecException

* @throws NoSuchAlgorithmException

*/

public static PrivateKey bytesToPrivateKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
byte[] encodedKey = Base64.getDecoder().decode(bytes);

KeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);

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

return keyFactory.generatePrivate(keySpec);

}
/**

* 将x509 base64 byte数组转为公钥

*

* @param bytes

* @return

* @throws InvalidKeySpecException

* @throws NoSuchAlgorithmException

*/

public static PublicKey bytesToPublicKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
byte[] encodedKey = Base64.getDecoder().decode(bytes);

KeySpec keySpec = new X509EncodedKeySpec(encodedKey);

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

return keyFactory.generatePublic(keySpec);

}

服务器端利用上述代码生成密钥代码如下:

    

static KeyPair kp ;
static PublicKey publicKey;//为了使验证时,使用与生成密钥时对应的公钥,在此设置为静态域。
public String getmy(String str) throws Exception {

Map map=new HashMap();

String name;

String userid=(String)map.get("userid");

String jh100005=(String)map.get("jh100005");

String service=(String)map.get("service");


Map map2=new HashMap();

kp = RSAUtils.generateKeyPair();

long rtime = new Date().getTime();

String rtimes = Long.toString(rtime);

String ser=(String)map.get("service");

String content = rtimes + userid+ser;

String sign = RSAUtils.sign(content, kp.getPrivate());//生成密钥


publicKey=kp.getPublic();//publicKey为静态域,

System.out.println("publickey="+publicKey);

String publickeystring=keyToString(publicKey);

//计算24小时之后时间,设定密钥的有效期。

Date date=new Date();

Calendar cal=new GregorianCalendar();

cal.setTime(date);

cal.add(cal.DATE, 1);

Date tomorrow=cal.getTime();

long tomortime=tomorrow.getTime();

return sign ;}

验证密钥:


public String verify(String str) throws Exception {
ExchViewSerService exchViewSerService = (ExchViewSerService) ServiceLocator.getService("exchViewSerService");
Map map=new HashMap();
String yzmy= (String) map.get("yzmy");//获取用户输入的密钥字段。
String hmopubkey;//公钥
String content;//生成密钥时使用的字符串。
    HashMap hmo1=(HashMap)o; //o为从数据库中读取的密钥相关字段,为一个map对象。
hmopubkey=(String)hmo1.get("publickeystring");//取出公钥字符
        content=(String)hmo1.get("content");//取出内容。
        long date= Long.parseLong(hmo1.get("signeffectime").toString());//取出密钥有效终止日期
        System.out.println(date);
    //判断是否过期
    Date datenow=new Date();
    long sub=date-datenow.getTime();
    System.out.println(sub);
    if(sub<0){
    map.put("mygq","密钥过期");
    return "密钥过期";
}
boolean sucessflag=RSAUtils.verify(content,yzmy,publicKey);//判断密钥是否正确。
map.put("flag", sucessflag);
if(sucessflag){
System.out.println("sucess");
return "sucess";}
else{
return "false";
}
}
整个生成验证的流程就完成了。



最后

以上就是传统人生为你收集整理的通过Rsa加密验证。的全部内容,希望文章能够帮你解决通过Rsa加密验证。所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部