使用java rsa 签名和验签,生成私钥和公钥

本文介绍了一种基于Java的RSA签名及验证方法的实现细节。通过具体的代码示例展示了如何生成RSA公钥和私钥,并利用这些密钥完成数据签名与验证的过程。此外,还提供了一个实用的工具类,用于简化签名生成和签名验证的操作。
package com.twodfire.alipay.utils;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import java.util.SortedMap;

/**
* Created by Administrator on 2015/12/25.
*/
public class RsaCipherHelper {
private static final String GOUQI_PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIodOSS4fXlvWYrgJdOCeLhBCsei" +
"CBaYqolfdViVCIETXJWQovUf1qRUtFyUaO4uh/2I0zx125MWA/Nr8Lz3iRSm2MfA62aON019Qsl8" +
"iAztT3a3Qe9duavhrNqyILX+QMyOIuHHHObD0ChbgsuBINrJ2OttDH+LP7Wss3kO4eMdAgMBAAEC" +
"gYAUmIkF9dEYQ8eZkxVw9hrkdyaRYJNOM1PzCl4oaIkNHoMG9rumTCoo9Uy0JZmEM0IqR7YgZP7q" +
"bzUFnsoWk99IESL98WnEZg+ze7xQdv0fwPA1c43MhzD+i1a0LWPS10HlO+M7PfQyWWguHa3os+aQ" +
"DSyYrHg6M+e6tkh4X7yf7QJBAODPtGe0F7XtXKVwvO+lnEzYw7mKhEsB6Rtz/bV/AVRsmT4ahnnb" +
"dCFvyyInEZ56faJyxjVhdB85TZ29ESHl9VcCQQCdRmvZePTlpT2vxjQswtRtOlzekIRgm19vgu2X" +
"foUyVgISiqvl0+uPHAju9wYkkyNm001l9OVU5uo+0LiMHc6rAkAL28j3Y2+QwCmP7Id62LCK+TAx" +
"3FWoIzypnw+2ADIQwv2+YeXQDbxtexkq/waV5n40EHvWGwLmFr66YFvD/v5XAkA2CneOf2Bu9Etw" +
"9YMCCmQhsBcvJqtF4r11PKDVGFU+SY1mv513WE0tnG15ZwoGUUSt1VdX/EE822fT87Yl9ywHAkBG" +
"7hb76FMfc9dXXxMSxeP+HVk0M6BW0GCNZWp2xE6yYxLvesy1IeLUOrsHjhd6JhvUc0+Ym91F7kNn" +
"aXqPCDRd";

private static final String GOUQI_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKHTkkuH15b1mK4CXTgni4QQrHoggWmKqJX3VY" +
"lQiBE1yVkKL1H9akVLRclGjuLof9iNM8dduTFgPza/C894kUptjHwOtmjjdNfULJfIgM7U92t0Hv" +
"Xbmr4azasiC1/kDMjiLhxxzmw9AoW4LLgSDaydjrbQx/iz+1rLN5DuHjHQIDAQAB";

/**
* 生成签名
*
* @param content
* @param privateKey
* @return
*/
public static String sign(String content, String privateKey) {
return sign(content, str2PrivateKey(privateKey));
}

/**
* 验证签名
*
* @param content
* @param publicKey
* @return
*/
public static boolean verify(String content, String sign, String publicKey) {
return verify(content, sign, str2PublicKey(publicKey));
}

/**
* @param content
* @param privateKey
* @return
*/
public static String sign(String content, RSAPrivateKey privateKey) {
try {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(content.getBytes("utf-8"));
return new BASE64Encoder().encode(signature.sign());
} catch (Exception e) {
throw new RuntimeException(e);
}
}

/**
* @param content
* @param publicKey
* @return
*/
public static boolean verify(String content, String sign, RSAPublicKey publicKey) {
try {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(publicKey);
signature.update(content.getBytes("utf-8"));
return signature.verify((new BASE64Decoder()).decodeBuffer(sign));
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static RSAPublicKey str2PublicKey(String publicKeyPerm) {
try {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec((new BASE64Decoder()).decodeBuffer(publicKeyPerm));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static RSAPrivateKey str2PrivateKey(String privateKeyPerm) {
try {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec((new BASE64Decoder()).decodeBuffer(privateKeyPerm));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

/**
* 将所有POST 参数(sign除外)进行字典排序,组成字符串, 然后使用私钥产生签名
* @param params
* @return sign
*/
public static String encodeParams(SortedMap<?, ?> params, String privateKey) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<?, ?> entry : params.entrySet()) {
sb.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}

sb.deleteCharAt(sb.length() - 1);
return sign(sb.toString(), privateKey);
}

public static void main2(String[] args) throws Exception {

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

BASE64Encoder base64Encoder = new BASE64Encoder();
System.out.println("-------------------public key----------------------");
System.out.println(base64Encoder.encode(publicKey.getEncoded()));
System.out.println("-------------------private key---------------------");
System.out.println(base64Encoder.encode(privateKey.getEncoded()));

}

public static void main3(String[] args) {
String publicKey = GOUQI_PUBLIC_KEY;
String privateKey = GOUQI_PRIVATE_KEY;

String appPrivateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAN0yqP" +
"kLXlnhM+2H/57aHsYHaHXazr9pFQun907TMvmbR04wHChVsKVgGUF1hC0FN" +
"9hfeYT5v2SXg1WJSg2tSgk7F29SpsF0I36oSLCIszxdu7ClO7c22mxEVuCj" +
"mYpJdqb6XweAZzv4Is661jXP4PdrCTHRdVTU5zR9xUByiLSVAgMBAAECgYEAh" +
"znORRonHylm9oKaygEsqQGkYdBXbnsOS6busLi6xA+iovEUdbAVIrTCG9t854" +
"z2HAgaISoRUKyztJoOtJfI1wJaQU+XL+U3JIh4jmNx/k5UzJijfvfpT7Cv3ueM" +
"tqyAGBJrkLvXjiS7O5ylaCGuB0Qz711bWGkRrVoosPM3N6ECQQD8hVQUgnHEVH" +
"ZYtvFqfcoq2g/onPbSqyjdrRu35a7PvgDAZx69Mr/XggGNTgT3jJn7+2XmiGkH" +
"M1fd1Ob/3uAdAkEA4D7aE3ZgXG/PQqlm3VbE/+4MvNl8xhjqOkByBOY2ZFfWKh" +
"lRziLEPSSAh16xEJ79WgY9iti+guLRAMravGrs2QJBAOmKWYeaWKNNxiIoF7/4" +
"VDgrcpkcSf3uRB44UjFSn8kLnWBUPo6WV+x1FQBdjqRviZ4NFGIP+KqrJnFHzN" +
"gJhVUCQFzCAukMDV4PLfeQJSmna8PFz2UKva8fvTutTryyEYu+PauaX5laDjyQ" +
"bc4RIEMU0Q29CRX3BA8WDYg7YPGRdTkCQQCG+pjU2FB17ZLuKRlKEdtXNV6zQ" +
"FTmFc1TKhlsDTtCkWs/xwkoCfZKstuV3Uc5J4BNJDkQOGm38pDRPcUDUh2/";

String sign = sign("jackiezhi", appPrivateKey);
System.out.println(sign);
//System.out.println(verify("jackiezhi", sign, publicKey));


}

}
在数字签名的过程中,是使用**私钥签名**,而使用**公钥进行**。数字签名的核心目的是确保数据的完整性发送者的身份证。 数字签名的原理可以分为以下几个步骤: 1. **生成消息摘要**:发送方首先使用一个哈希函数对原始消息生成一个固定长度的消息摘要,这个摘要具有唯一性,即使消息发生微小变化,摘要也会完全不同。 2. **私钥签名**:发送方使用自己的私钥对该消息摘要进行加密,这个加密后的结果就是数字签名。 3. **传输**:发送方将原始消息数字签名一起发送给接收方。 4. **公钥**:接收方使用发送方的公钥对数字签名进行解密,得到消息摘要。同时,接收方使用相同的哈希函数对收到的原始消息重新生成消息摘要。 5. **比对摘要**:接收方将解密得到的消息摘要与自己生成的消息摘要进行比对。如果两者一致,说明消息没有被篡改,并且确认了发送方的身份[^3]。 ### 公钥私钥的作用 - **私钥**:用于生成数字签名,只有持有私钥的发送方才能生成有效的签名。 - **公钥**:用于证数字签名,任何人都可以使用发送方的公钥签名的有效性[^2]。 通过这种方式,数字签名确保了数据的真实性完整性,同时也提供了不可否认性(即发送方无法否认其签名)。 ### 示例代码:生成RSA密钥对并进行数字签名 以下是一个使用Python的`cryptography`库生成RSA密钥对并进行数字签名的示例: ```python from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.backends import default_backend # 生成RSA密钥对 private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) public_key = private_key.public_key() # 将私钥序列化为PEM格式 private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) # 将公钥序列化为PEM格式 public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # 原始消息 message = b"Hello, this is a message to be signed." # 使用私钥进行签名 signature = private_key.sign( message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) # 使用公钥签名 try: public_key.verify( signature, message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) print("Signature is valid.") except Exception as e: print("Signature is invalid:", e) ``` ### 解释 - **生成密钥对**:使用`rsa.generate_private_key`生成一个2048位的RSA私钥,并从私钥中提取公钥。 - **签名**:使用私钥对消息进行签名签名过程使用了PSS填充方案SHA-256哈希算法。 - **证**:使用公钥签名进行证,如果签名有效,则输出“Signature is valid.”;否则,输出错误信息。 通过这种方式,数字签名确保了消息的完整性发送者的身份证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值