first commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user