RSA 公钥格式转换之PHP实现
source link: https://blogread.cn/it/article/985?f=hot1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
RSA 公钥格式转换之PHP实现
在.net中公钥的格式总是以modules 、exponent的格式存在的,但是openssl做加密、解密总是使用pem格式的,这里实现了前者到后者的格式转换。
.net生成的public key的格式:
<modulus>
jY39vkCL8xCrUK9eepK2SQ447xiU/bZmnJi6G+4ripHzOJ65YTsxJ3sEOrXCyb0P
MBXQchQ2xpE8g7PyHe4zv07/Q7hbRFJ2CJAIyFj7OD5aejOiIptMzPsYNMx5Gkbs
</modulus>
<exponent>
AQAB
</exponent>
<?php
/**
* Zeal Extends of ZendFramework
*
* @category Zeal
* @package Zeal
* @subpackage Security
*/
/**
* RSA公钥格式转化
*
* @category Zeal
* @package Zeal
* @subpackage Security
*/
class Zeal_Security_RSAPublicKey
{
/**
* ASN.1 type INTEGER class
*/
const ASN_TYPE_INTEGER = 0x02;
/**
* ASN.1 type BIT STRING class
*/
const ASN_TYPE_BITSTRING = 0x03;
/**
* ASN.1 type SEQUENCE class
*/
const ASN_TYPE_SEQUENCE = 0x30;
/**
* The Identifier for RSA Keys
*/
const RSA_KEY_IDENTIFIER = '300D06092A864886F70D0101010500';
/**
* Constructor (disabled)
*
* @return void
*/
private function __construct()
{
}
/**
* Transform an RSA Key in x.509 string format into a PEM encoding and
* return an PEM encoded string for openssl to handle
*
* @param string $certificate x.509 format cert string
* @return string The PEM encoded version of the key
*/
static public function getPublicKeyFromX509($certificate)
{
$publicKeyString = "-----BEGIN CERTIFICATE-----n" .
wordwrap($certificate, 64, "n", true) .
"n-----END CERTIFICATE-----";
return $publicKeyString;
}
/**
* Transform an RSA Key in Modulus/Exponent format into a PEM encoding and
* return an PEM encoded string for openssl to handle
*
* @param string $modulus The RSA Modulus in binary format
* @param string $exponent The RSA exponent in binary format
* @return string The PEM encoded version of the key
*/
static public function getPublicKeyFromModExp($modulus, $exponent)
{
$modulusInteger = self::_encodeValue($modulus,
self::ASN_TYPE_INTEGER);
$exponentInteger = self::_encodeValue($exponent,
self::ASN_TYPE_INTEGER);
$modExpSequence = self::_encodeValue($modulusInteger .
$exponentInteger,
self::ASN_TYPE_SEQUENCE);
$modExpBitString = self::_encodeValue($modExpSequence,
self::ASN_TYPE_BITSTRING);
$binRsaKeyIdentifier = pack( "H*", self::RSA_KEY_IDENTIFIER );
$publicKeySequence = self::_encodeValue($binRsaKeyIdentifier .
$modExpBitString,
self::ASN_TYPE_SEQUENCE);
$publicKeyInfoBase64 = base64_encode( $publicKeySequence );
$publicKeyString = "-----BEGIN PUBLIC KEY-----n";
$publicKeyString .= wordwrap($publicKeyInfoBase64, 64, "n", true);
$publicKeyString .= "n-----END PUBLIC KEY-----n";
return $publicKeyString;
}
/**
* Encode a limited set of data types into ASN.1 encoding format
* which is used in X.509 certificates
*
* @param string $data The data to encode
* @param const $type The encoding format constant
* @return string The encoded value
* @throws Zend_InfoCard_Xml_Security_Exception
*/
static protected function _encodeValue($data, $type)
{
// Null pad some data when we get it
// (integer values > 128 and bitstrings)
if( (($type == self::ASN_TYPE_INTEGER) && (ord($data) > 0x7f)) ||
($type == self::ASN_TYPE_BITSTRING)) {
$data = "�$data";
}
$len = strlen($data);
// encode the value based on length of the string
switch(true) {
case ($len < 128):
return sprintf("%c%c%s", $type, $len, $data);
case ($len < 0x0100):
return sprintf("%c%c%c%s", $type, 0x81, $len, $data);
case ($len < 0x010000):
return sprintf("%c%c%c%c%s", $type, 0x82,
$len / 0x0100,
$len % 0x0100, $data);
default:
throw
new Zeal_Security_RSAPublicKey_Exception("Could not encode value",1);
}
throw
new Zeal_Security_RSAPublicKey_Exception("Invalid code path",2);
}
}
class Zeal_Security_RSAPublicKey_Exception extends Exception
{
}
// example
$hCert = openssl_pkey_get_public(
Zeal_Security_RSAPublicKey::getPublicKeyFromModExp(
file_get_contents("/home/zeal/certs/public.key"),
"AQAB"
)
);
$dataToCheck = "This is Data should be verified!";
$signBinary = ".................................";
$ok = openssl_verify(
$dataToCheck,
$signBinary,
$hCert,
OPENSSL_ALGO_SHA1
);
if ($ok == 1) {
echo "good";
}
elseif ($ok == 0) {
echo "bad";
}
else {
echo "error occured";
}
?>
建议继续学习:
扫一扫订阅我的微信号:IT技术博客大学习
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK