Files
pay/includes/vendor/cccyun/wechatpay-sdk/src/RsaTool.php
T
2025-11-28 10:08:12 +08:00

75 lines
2.3 KiB
PHP

<?php
namespace WeChatPay;
class RsaTool
{
/**
* @var string - Equal to `sequence(oid(1.2.840.113549.1.1.1), null))`
* @link https://datatracker.ietf.org/doc/html/rfc3447#appendix-A.2
*/
private const ASN1_OID_RSAENCRYPTION = '300d06092a864886f70d0101010500';
private const ASN1_SEQUENCE = 48;
private const CHR_NUL = "\0";
private const CHR_ETX = "\3";
/**
* Translate the \$thing strlen from `X690` style to the `ASN.1` 128bit hexadecimal length string
*
* @param string $thing - The string
*
* @return string The `ASN.1` 128bit hexadecimal length string
*/
private static function encodeLength(string $thing): string
{
$num = strlen($thing);
if ($num <= 0x7F) {
return sprintf('%c', $num);
}
$tmp = ltrim(pack('N', $num), self::CHR_NUL);
return pack('Ca*', strlen($tmp) | 0x80, $tmp);
}
/**
* Convert the `PKCS#1` format RSA Public Key to `SPKI` format
*
* @param string $thing - The base64-encoded string, without evelope style
*
* @return string The `SPKI` style public key without evelope string
*/
public static function pkcs1ToSpki(string $thing): string
{
$raw = self::CHR_NUL . base64_decode($thing);
$new = pack('H*', self::ASN1_OID_RSAENCRYPTION) . self::CHR_ETX . self::encodeLength($raw) . $raw;
return base64_encode(pack('Ca*a*', self::ASN1_SEQUENCE, self::encodeLength($new), $new));
}
public static function pemToBase64(string $data): string
{
$line = explode("\n", $data);
$base64 = '';
foreach($line as $row){
if(empty($row) || strpos($row, '-----BEGIN')!==false || strpos($row, '-----END')!==false) continue;
$base64 .= trim($row);
}
return $base64;
}
public static function base64ToPem(string $data, $type): string
{
if(empty($data) || strpos($data, '-----BEGIN')!==false) return $data;
$pem = "-----BEGIN ".$type."-----\n" .
wordwrap($data, 64, "\n", true) .
"\n-----END ".$type."-----";
return $pem;
}
public static function pkcs1ToSpkiPem(string $thing): string
{
$raw = self::pemToBase64($thing);
$new = self::pkcs1ToSpki($raw);
return self::base64ToPem($new, 'PUBLIC KEY');
}
}