PHP与JAVA的签名与验签比较

本文探讨在PHP和JAVA之间进行签名与验签时如何保持一致性。通过示例代码展示PHP和JAVA的签名验签过程,指出两者在Base64解码和算法选择上的区别,帮助开发者理解跨语言协作时的细节问题。

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

往期精选(欢迎转发~~)

<?php
class RsaUtil {
	/**
	 * 获取签名
	 * @param string $strData 加密数据
	 * @param string $privateKey 私钥
	 * @return string $signature 签名
	 */
	static function sign($strData, $privateKey) {
		if (!openssl_get_privatekey($privateKey)) {
			echo 'encryptTaiping openssl_get_privatekey failed.';
			return false;
		}
		$signature = '';
		if (!openssl_sign($strData, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
			echo 'openssl_sign failed.';
			return false;
		}
		$signature = base64_encode($signature);
		return $signature;
	}
	
	/**
	 *
	 * RSA验签
	 * @param string $strData 验签数据
	 * @param string $signature 签名
	 * @return boolean true-成功 false-失败
	 */
	static function verify($strData, $signature, $publicKey) {
		if (!openssl_get_publickey($publicKey)) {
			echo 'verifyTaiping openssl_get_publickey failed.';
			return false;
		}
		$base64Signature = base64_decode($signature);
		if (!openssl_verify($strData, $base64Signature, $publicKey, OPENSSL_ALGO_SHA256)) {
			echo 'openssl_verify failed.';
			return false;
		}
		return true;
	}
}

$privateKey = '-----BEGIN RSA PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJXlLTA3tgArTApBu
KO9W8oIZq2p8AnZkx/6/2OCD/KMMRk7oUwev820ePBeT3J1IsKNsmgWLqsJ07J0SM
h/aVy7HBX6KPxueCilxa8yPFCdB0ZcLogFhN+2Rt6U0xGzRQ6WithR0XWZ6/aw4MX
xoioUzdkFGoExrsC/bTBLcWW3AgMBAAECgYAxVtJdALmDrLzG04M3QmkoQ0Oo/jro
wxlOeYv+8RzWtZaju6EIMUbpKvJ0DFcSUcQzTfjfkg2idwWbw/MBLA891mNO2P2qq
nKEq2leHlQN3PwH216nYfJ/24qiIi3lv1D9/H3QZ+qvq0e6m2gQMSbrAygPN3eNTY
3NUj6tqT2foQJBAPak9EiVZJ4wzD4KHGaC9rKWIst2j3Db5JBH2jsf73GI2yQcrZw
ceIR0mGREDxRA5VQkPw+YV63378ExwWSzgOsCQQCblLzRkIL5LtR6jb9rktoFqqlK
3K3nqTJs7sNCxZmgc14/EkGd42sLyi3kJhgdPHpqU9gmIZnoaAgCUIKyZFtlAkB9k
DSczxFOR2FzJAqZVYrqF+zW0CDuP8P4f9vlxbhMgHOvyrnHg+cG56S9Rri2guM9Fs
bT1aatdk+kdwQRlCDJAkA7WdViOLfOKXBDRFnWxtHHQaCNf3wUGPa0ma0BhvIhRIG
am/NOMRiACePR2jpuxMiKUWvut/jHsRAFGgOR3DkFAkAX6tPWaLK7vUPoydjX97y0
N5bPEaAyKhRn/U4IzoH8wgkbNQ+ktxZ8FLP5cUJOOlBtoCePbk52UexV4TqpZK++
-----END RSA PRIVATE KEY-----';
$publicKey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCV5S0wN7YAK0wKQbijvVvKCGatqf
AJ2ZMf+v9jgg/yjDEZO6FMHr/NtHjwXk9ydSLCjbJoFi6rCdOydEjIf2lcuxwV+ij8
bngopcWvMjxQnQdGXC6IBYTftkbelNMRs0UOlorYUdF1mev2sODF8aIqFM3ZBRqBMa
7Av20wS3FltwIDAQAB
-----END PUBLIC KEY-----';

$textData = 'hello world!';
$strSignature = RsaUtil::sign($textData, $privateKey);
echo '签名:' . $strSignature . "\n";
$bolVerify = RsaUtil::verify($textData, $strSignature, $publicKey);
echo '验签:' . $bolVerify . "\n";

输出结果为:
  这里写图片描述
  
2 JAVA签名与验签
  下面在上java代码前,有个小问题需要说明一下,java程序中需要包含base64的jar库,该库可以在该地址下载:http://download.youkuaiyun.com/download/yx0628/5842065,具体导入jar库的方法,网上很多,我就不多介绍了,下面直接上代码:

import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import it.sauronsoftware.base64.Base64;

public class RsaUtil {
	//RSA签名 
	//text:待签名的数据,privateKeyData:第三方的私钥
	private static byte[] sign(final byte[] text, final byte[] privateKeyData) throws GeneralSecurityException {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyData);
		KeyFactory keyFactory 		= KeyFactory.getInstance("RSA");
		PrivateKey privateKey 		= keyFactory.generatePrivate(keySpec);
		Signature signatureChecker 	= Signature.getInstance("SHA256WITHRSA");
		signatureChecker.initSign(privateKey);
		signatureChecker.update(text);
		return signatureChecker.sign();
	}
	
	//RSA验签名检查 
	//text:待签名数据,signedText:签名值,publicKeyData:开发商公钥
	private static boolean verify(final byte[] text, final byte[] signedText, final byte[] publicKeyData) throws GeneralSecurityException {
		X509EncodedKeySpec keySpec 	= new X509EncodedKeySpec(publicKeyData);
		KeyFactory keyFactory 		= KeyFactory.getInstance("RSA");
		PublicKey publicKey 		= keyFactory.generatePublic(keySpec);
		Signature signatureChecker 	= Signature.getInstance("SHA256WITHRSA");
		signatureChecker.initVerify(publicKey);
		signatureChecker.update(text);
		return signatureChecker.verify(signedText);
	}
	
	public static void main(String args[]) throws GeneralSecurityException, RuntimeException {
		String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJXlLTA3tgArTApBuKO9W8oIZq2p8AnZkx/6/2OCD/KMMRk7oUwev820ePBeT3J1IsKNsmgWLqsJ07J0SMh/aVy7HBX6KPxueCilxa8yPFCdB0ZcLogFhN+2Rt6U0xGzRQ6WithR0XWZ6/aw4MXxoioUzdkFGoExrsC/bTBLcWW3AgMBAAECgYAxVtJdALmDrLzG04M3QmkoQ0Oo/jrowxlOeYv+8RzWtZaju6EIMUbpKvJ0DFcSUcQzTfjfkg2idwWbw/MBLA891mNO2P2qqnKEq2leHlQN3PwH216nYfJ/24qiIi3lv1D9/H3QZ+qvq0e6m2gQMSbrAygPN3eNTY3NUj6tqT2foQJBAPak9EiVZJ4wzD4KHGaC9rKWIst2j3Db5JBH2jsf73GI2yQcrZwceIR0mGREDxRA5VQkPw+YV63378ExwWSzgOsCQQCblLzRkIL5LtR6jb9rktoFqqlK3K3nqTJs7sNCxZmgc14/EkGd42sLyi3kJhgdPHpqU9gmIZnoaAgCUIKyZFtlAkB9kDSczxFOR2FzJAqZVYrqF+zW0CDuP8P4f9vlxbhMgHOvyrnHg+cG56S9Rri2guM9FsbT1aatdk+kdwQRlCDJAkA7WdViOLfOKXBDRFnWxtHHQaCNf3wUGPa0ma0BhvIhRIGam/NOMRiACePR2jpuxMiKUWvut/jHsRAFGgOR3DkFAkAX6tPWaLK7vUPoydjX97y0N5bPEaAyKhRn/U4IzoH8wgkbNQ+ktxZ8FLP5cUJOOlBtoCePbk52UexV4TqpZK++";
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCV5S0wN7YAK0wKQbijvVvKCGatqfAJ2ZMf+v9jgg/yjDEZO6FMHr/NtHjwXk9ydSLCjbJoFi6rCdOydEjIf2lcuxwV+ij8bngopcWvMjxQnQdGXC6IBYTftkbelNMRs0UOlorYUdF1mev2sODF8aIqFM3ZBRqBMa7Av20wS3FltwIDAQAB";
		
		String textData = "hello world!";	
		byte[] base64PrivateKey = Base64.decode(privateKey.getBytes()); 
		byte[] base64PublicKey  = Base64.decode(publicKey.getBytes()); 
		
		byte[] signBytes = RsaUtil.sign(textData.getBytes(), base64PrivateKey);
		String strSignature = new String(Base64.encode(signBytes));
		System.out.println("签名:  " + strSignature);
		boolean bolVerify = verify(textData.getBytes(), signBytes, base64PublicKey);
		System.out.println("验签:  " + bolVerify);
    }
}

输出结果为(截取部分):
  这里写图片描述
  
3 比较
  两种语言生成的签名完全相同,但是生成签名和验签的过程中,有个明显的不同之处,即java进行签名和验签前,需要将key进行Base64.decode(),这个在php中不需要(我们用php,开始业务方给我们java的签名和验签示例时,看到java对key进行Base64.decode(),我以为php也需要对key进行相同处理,结果加密和验签一直失败)。然后对于签名和验签的算法,php中用到的是OPENSSL_ALGO_SHA256,对应的是java中的SHA256WITHRSA,这个需要自己查阅资料才能知道哈。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值