SHA256withRSA签名验签

本文介绍了一种基于RSA算法的数字签名实现方法,包括密钥生成、签名及验证过程。通过具体代码示例展示了如何使用Java进行RSA签名与验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码:

RSA.java

 


import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSA {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
    public static final String PUBLIC_KEY = "publicKey";
    public static final String PRIVATE_KEY = "privateKey";
    public static final int KEY_SIZE = 2048;
    /**
     * 生成密钥对
     * 
     * @return
     */
    public static Map<String, byte[]> generateKeyBytes() {

        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator
                    .getInstance(KEY_ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            Map<String, byte[]> keyMap = new HashMap<String, byte[]>();
            keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
            keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 还原公钥
     * 
     * @param keyBytes
     * @return
     */
    public static PublicKey restorePublicKey(byte[] keyBytes) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 还原私钥
     * 
     * @param keyBytes
     * @return
     */
    public static PrivateKey restorePrivateKey(byte[] keyBytes) {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
                keyBytes);
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = factory
                    .generatePrivate(pkcs8EncodedKeySpec);
            return privateKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Demo.java

 

 

import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Map;

public class Demo {

	public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
	public static final String ENCODE_ALGORITHM = "SHA-256";
	public static final String PLAIN_TEXT = "test string";

	public static void main(String[] args) {
		// 公私钥对
		Map<String, byte[]> keyMap = RSA.generateKeyBytes();
		PublicKey publicKey = RSA.restorePublicKey(keyMap.get(RSA.PUBLIC_KEY));
		PrivateKey privateKey = RSA.restorePrivateKey(keyMap.get(RSA.PRIVATE_KEY));
		// 签名
		byte[] sing_byte = sign(privateKey, PLAIN_TEXT);
		// 验签
		verifySign(publicKey, PLAIN_TEXT, sing_byte);
	}

	/**
	 * 签名
	 * 
	 * @param privateKey
	 *            私钥
	 * @param plain_text
	 *            明文
	 * @return
	 */
	public static byte[] sign(PrivateKey privateKey, String plain_text) {
		MessageDigest messageDigest;
		byte[] signed = null;
		try {
			messageDigest = MessageDigest.getInstance(ENCODE_ALGORITHM);
			messageDigest.update(plain_text.getBytes());
			byte[] outputDigest_sign = messageDigest.digest();
			System.out.println("SHA-256加密后-----》" +bytesToHexString(outputDigest_sign));
			Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM);
			Sign.initSign(privateKey);
			Sign.update(outputDigest_sign);
			signed = Sign.sign();
			System.out.println("SHA256withRSA签名后-----》" + bytesToHexString(signed));
		} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
			e.printStackTrace();
		}
		return signed;
	}

	/**
	 * 验签
	 * 
	 * @param publicKey
	 *            公钥
	 * @param plain_text
	 *            明文
	 * @param signed
	 *            签名
	 */
	public static boolean verifySign(PublicKey publicKey, String plain_text, byte[] signed) {

		MessageDigest messageDigest;
		boolean SignedSuccess=false;
		try {
			messageDigest = MessageDigest.getInstance(ENCODE_ALGORITHM);
			messageDigest.update(plain_text.getBytes());
			byte[] outputDigest_verify = messageDigest.digest();
			//System.out.println("SHA-256加密后-----》" +bytesToHexString(outputDigest_verify));
			Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
			verifySign.initVerify(publicKey);
			verifySign.update(outputDigest_verify);
			SignedSuccess = verifySign.verify(signed);
			System.out.println("验证成功?---" + SignedSuccess);
			
		} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
			e.printStackTrace();
		}
		return SignedSuccess;
	}

	/**
	 * bytes[]换成16进制字符串
	 * 
	 * @param src
	 * @return
	 */
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
}

 

 

 

 

 

 

 

### SHA256withRSA 签名证的 C 语言实现 为了实现在 C 语言中使用 SHA256withRSA 进行签名证的操作,通常依赖 OpenSSL 库来处理哈希函数以及 RSA 密码学操作。下面提供了一个简单的例子说明如何创建并证一个基于 SHA256RSA 的数字签名。 #### 函数定义 首先引入必要的头文件: ```c #include <openssl/sha.h> #include <openssl/pem.h> #include <openssl/rsa.h> #include <openssl/bio.h> ``` 接着定义用于生成签名的方法 `signData` 及其对应的参数结构体 `SignatureParams`: ```c typedef struct { unsigned char* data; // 待签名的数据指针 size_t length; // 数据长度 EVP_PKEY *privateKey; // 私钥对象 } SignatureParams; int signData(SignatureParams params, unsigned char **signature, unsigned int *sigLen); ``` 同样地,定义用于签名的方法 `verifySignature` 及其所需的输入数据类型 `VerificationParams` : ```c typedef struct { const unsigned char* signature; unsigned int sigLen; const unsigned char* originalData; size_t origLen; EVP_PKEY *publicKey; } VerificationParams; int verifySignature(VerificationParams verificationParams); ``` #### 实现细节 下面是具体的实现逻辑,包括初始化上下文、执行摘要计算、应用私钥完成签名过程等步骤[^1]。 对于签名部分: ```c int signData(SignatureParams params, unsigned char **signature, unsigned int *sigLen){ EVP_MD_CTX *mdctx = NULL; mdctx = EVP_MD_CTX_new(); if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, params.privateKey) <= 0) goto err; if (EVP_DigestSignUpdate(mdctx, params.data, params.length) <= 0) goto err; /* Determine the size of digest value */ if(EVP_DigestSignFinal(mdctx, NULL, sigLen)<=0) goto err; *signature=(unsigned char*)OPENSSL_malloc(*sigLen); if(!*signature || EVP_DigestSignFinal(mdctx,*signature,sigLen)<=0) goto err; EVP_MD_CTX_free(mdctx); return 1; err: if(mdctx != NULL) EVP_MD_CTX_free(mdctx); return 0; } ``` 而对于证,则需重复上述大部分流程,只是最后一步变为调用 `EVP_VerifyFinal()` 来比较接收到的消息摘要与重新计算的结果是否一致。 ```c int verifySignature(VerificationParams verificationParams){ EVP_MD_CTX *mdctx = NULL; mdctx = EVP_MD_CTX_new(); if (EVP_VerifyInit_ex(mdctx, EVP_sha256(),NULL) <= 0) goto err; if (EVP_VerifyUpdate(mdctx,verificationParams.originalData, verificationParams.origLen) <= 0) goto err; int result = EVP_VerifyFinal(mdctx,(const unsigned char *)verificationParams.signature, verificationParams.sigLen,verificationParams.publicKey); EVP_MD_CTX_free(mdctx); return result>0?1:0; err: if(mdctx!=NULL) EVP_MD_CTX_free(mdctx); return 0; } ``` 以上代码片段展示了如何利用 OpenSSL 提供的功能,在 C 中实现了 SHA256withRSA签名证功能。需要注意的是实际部署时还需要考虑错误处理机制和其他安全措施以确保系统的健壮性和安全性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu_Dag

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值