Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/changelog/1848-from-description
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

hs2019 signatures for incoming REST API requests now have their algorithm determined based on their public key.
65 changes: 50 additions & 15 deletions includes/class-signature.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,19 @@ public static function verify_http_signature( $request ) {
return new WP_Error( 'activitypub_signature', __( 'Incompatible request signature. keyId and signature are required', 'activitypub' ), array( 'status' => 401 ) );
}

$public_key = self::get_remote_key( $signature_block['keyId'] );
if ( \is_wp_error( $public_key ) ) {
return $public_key;
}

$signed_data = self::get_signed_data( $signature_block['headers'], $signature_block, $headers );
if ( ! $signed_data ) {
return new WP_Error( 'activitypub_signature', __( 'Signed request date outside acceptable time window', 'activitypub' ), array( 'status' => 401 ) );
}

$algorithm = self::get_signature_algorithm( $signature_block );
if ( ! $algorithm ) {
return new WP_Error( 'activitypub_signature', __( 'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)', 'activitypub' ), array( 'status' => 401 ) );
$algorithm = self::get_signature_algorithm( $signature_block, $public_key );
if ( \is_wp_error( $algorithm ) ) {
return $algorithm;
}

if ( \in_array( 'digest', $signature_block['headers'], true ) && isset( $body ) ) {
Expand All @@ -300,12 +305,6 @@ public static function verify_http_signature( $request ) {
}
}

$public_key = self::get_remote_key( $signature_block['keyId'] );

if ( \is_wp_error( $public_key ) ) {
return $public_key;
}

$verified = \openssl_verify( $signed_data, $signature_block['signature'], $public_key, $algorithm ) > 0;
if ( ! $verified ) {
return new WP_Error( 'activitypub_signature', __( 'Invalid signature', 'activitypub' ), array( 'status' => 401 ) );
Expand Down Expand Up @@ -347,21 +346,57 @@ public static function get_remote_key( $key_id ) {
/**
* Gets the signature algorithm from the signature header.
*
* @param array $signature_block The signature block.
* @see https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12
*
* @param array $signature_block The signature block.
* @param resource $public_key The public key resource.
*
* @return string|bool The signature algorithm or false if not found.
* @return int|\WP_Error The signature algorithm or WP_Error if not found.
*/
public static function get_signature_algorithm( $signature_block ) {
public static function get_signature_algorithm( $signature_block, $public_key ) {
if ( ! empty( $signature_block['algorithm'] ) ) {
switch ( $signature_block['algorithm'] ) {
case 'hs2019':
$details = \openssl_pkey_get_details( $public_key );

switch ( $details['type'] ?? 0 ) {
case \OPENSSL_KEYTYPE_RSA:
$bits = $details['bits'] ?? 2048;

if ( $bits >= 4 * KB_IN_BYTES ) {
return \OPENSSL_ALGO_SHA512;
} elseif ( $bits >= 3 * KB_IN_BYTES ) {
return \OPENSSL_ALGO_SHA384;
} else {
return \OPENSSL_ALGO_SHA256;
}

case \OPENSSL_KEYTYPE_EC:
$curve_name = $details['ec']['curve_name'] ?? '';

// 3 levels switch statements are fine, right?
switch ( $curve_name ) {
case 'prime256v1':
case 'secp256r1':
return \OPENSSL_ALGO_SHA256;
case 'secp384r1':
return \OPENSSL_ALGO_SHA384;
case 'secp521r1':
return \OPENSSL_ALGO_SHA512;
}
}

return new \WP_Error( 'unsupported_key_type', 'Unsupported key type (only RSA and EC keys are supported).', array( 'status' => 401 ) );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vpzomtrrfrt I'm curious if you'd have any advice on how this could be improved to switch algorithm="hs2019" support for wordpress-activitypub to "Yes"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't followed this space as closely lately, the last I heard was that there was no consensus on how keys should indicate their supported algorithms

case 'rsa-sha512':
return 'sha512'; // https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12.
return \OPENSSL_ALGO_SHA512;

default:
return 'sha256';
return \OPENSSL_ALGO_SHA256;
}
}
return false;

return new \WP_Error( 'unsupported_key_type', 'Unsupported signature algorithm (only rsa-sha256, rsa-sha512, and hs2019 are supported).', array( 'status' => 401 ) );
}

/**
Expand Down
41 changes: 41 additions & 0 deletions tests/fixtures/http-signature-keys.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"ec": {
"prime256v1": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8w60yJODBTjpve9ocBaYA3VL\/giZ\nGHD\/mh4caWcuPdfqyeF4Hh2ulS9byRJtsfuGXFQriBORTaIU\/vxQlZzQWw==\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAMScM2YsFV6coA+wC36tJ9yeBGi117nHbRcAVQ\/0dLDoAoGCCqGSM49\nAwEHoUQDQgAE8w60yJODBTjpve9ocBaYA3VL\/giZGHD\/mh4caWcuPdfqyeF4Hh2u\nlS9byRJtsfuGXFQriBORTaIU\/vxQlZzQWw==\n-----END EC PRIVATE KEY-----\n",
"algo": 7
},
"secp384r1": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE1yZjhG8eYvOcI9M3R\/mtNwdiflVKcqg2\njKD1lWwgqgrWsNXdYR4BUPcSr5Zc9z0xPdLfWx47qw+k\/sIDBnalplKjglYqzy0a\nbAz9Q6ay4dMnhqevDuipZY\/pCIZYi7yp\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDCtUTFk3dzuj9p8CTUfGHuMNCHjBjpJF3Np6GB4kJefpklDu+2CNlcI\nPXrKp3qMXCWgBwYFK4EEACKhZANiAATXJmOEbx5i85wj0zdH+a03B2J+VUpyqDaM\noPWVbCCqCtaw1d1hHgFQ9xKvllz3PTE90t9bHjurD6T+wgMGdqWmUqOCVirPLRps\nDP1DprLh0yeGp68O6Kllj+kIhliLvKk=\n-----END EC PRIVATE KEY-----\n",
"algo": 8
},
"secp521r1": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBh5Qusx4oKP7vZOHPOBE2vzZI5TS8\nPw2vWSSfXlfKg10nd61GjG09HL8+urjTwD2XHFKucnWDlmPsnL3r2kikDJkByqZq\nzgPD619cEMWJR14jPX1Yj2gACTtMTrm7xElIF\/2T27tymY2BlawR1S5pC+2Y3zuc\nQ1smx819jNn4gRSWFfw=\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN EC PRIVATE KEY-----\nMIHcAgEBBEIBV81ldPNoOGZwMdahdLlA9LewYJfMC24sMZSzzTJyO\/JUQLDTChtr\nG45FWEspDqHfBYai9LGEg1CGJAJuNbKckDmgBwYFK4EEACOhgYkDgYYABAGHlC6z\nHigo\/u9k4c84ETa\/NkjlNLw\/Da9ZJJ9eV8qDXSd3rUaMbT0cvz66uNPAPZccUq5y\ndYOWY+ycvevaSKQMmQHKpmrOA8PrX1wQxYlHXiM9fViPaAAJO0xOubvESUgX\/ZPb\nu3KZjYGVrBHVLmkL7ZjfO5xDWybHzX2M2fiBFJYV\/A==\n-----END EC PRIVATE KEY-----\n",
"algo": 9
},
"secp256k1": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE7HIhwVwFzSWrKMDHvEXaFbKLeb1luJ4G\n0pJFwyh3D4xhS81Q6bXkf6qax1HVwg1hf\/yEUjaypcHD4DEhrR9kiA==\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEINVm73\/bXz5ZCkRuJwpIvKpkm+5jXBadxCnSo4M5Yj1JoAcGBSuBBAAK\noUQDQgAE7HIhwVwFzSWrKMDHvEXaFbKLeb1luJ4G0pJFwyh3D4xhS81Q6bXkf6qa\nx1HVwg1hf\/yEUjaypcHD4DEhrR9kiA==\n-----END EC PRIVATE KEY-----\n",
"algo": 7
}
},
"rsa": {
"2048": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoTGqpRmnGyoBJY8JcsiI\nEE7SvSINqvfjn\/XRpWcwdowODiBIhP0xyuziC8lTikQquB+Rny+ftHjKlp1JwtC1\naW60wYSX38QPP1xJX8ERBKgtkYfo2XU8GV2bPx9+eJNXRMiPdHyyrhGln+ZIT3p9\nj20gjFIMrRz4QLqiJW+t1aPHcRysRiycenjimRAKw7q9gl7oXtYp66e52U3AYbmY\n38WikwXwoDUiuOS5DPJU78\/yMryr3qDEYNaTgLMqHRG+z7Yn8B+nBcWeSQL2k0zZ\nJ8bWknA9OmvVO1VQnJVqUa6nivnKiWpt9f\/yO1zauCLdg+9EDVocadMGlch\/474U\nxwIDAQAB\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChMaqlGacbKgEl\njwlyyIgQTtK9Ig2q9+Of9dGlZzB2jA4OIEiE\/THK7OILyVOKRCq4H5GfL5+0eMqW\nnUnC0LVpbrTBhJffxA8\/XElfwREEqC2Rh+jZdTwZXZs\/H354k1dEyI90fLKuEaWf\n5khPen2PbSCMUgytHPhAuqIlb63Vo8dxHKxGLJx6eOKZEArDur2CXuhe1inrp7nZ\nTcBhuZjfxaKTBfCgNSK45LkM8lTvz\/IyvKveoMRg1pOAsyodEb7PtifwH6cFxZ5J\nAvaTTNknxtaScD06a9U7VVCclWpRrqeK+cqJam31\/\/I7XNq4It2D70QNWhxp0waV\nyH\/jvhTHAgMBAAECggEACHv+QOFoR8g+tjTgqO+AJeeYNQdJU+HnU8CTD9MuHFdD\n2B9\/4awYBlfQkBFBOepbm0RiHFBb5hpjg2j0\/HGS0uFWV0c83TTLHqkjXYxicm3N\ntDbEnUmL58PjC4ADXqJWuhKaZmW32+ym3JM45CIM4NM8HtakvynisTmBllnZ+wAl\n7w4TJdUmNt+U3FdXNX2rrvt\/SKWqCAHCLEI2O0Wp\/HvJRZJCR8EPc8k\/oDxEFHg1\nOYDUkc9GQMQXl9KezG32GfxIv7g99r9N2j4bCnkvrADooQXMVPhIFvja5mWiE93P\nPkyO5+c4RKrBFl6Zf4oC\/DmO3v5BY58PkawXGdNMNQKBgQDX9EMwKsnIIsqOBcAK\nPJE+9nJ5OnbMeGwZFNKP+12\/AY1KftprFJZARrvAMcmIa2L2rEtRfDBK9x8SZfeM\nSorNw5poS+chEU8nh9TNjFki1hH3FWeKEVkMOZF8v5pz6EL0UKv7v8rr0hdKmFtE\nlvK7F58XmMq84obHE\/oRlaZi3QKBgQC\/Fdchy7uV49k+36nVfx5sbVWJvKmtQRSB\nCjanSpLS\/gmbjLDSBYdE8FhwMV3Wl8YsRJL3aQTSnWGJyzJ17cgGUD65EsNAh2LK\nNFNufDrVzwwjb6TRrfHK9GkcY2p4byS+Y4taT+dCny0PmdOx8xBCBUOpWmPuByJz\nn\/Zf6fLh8wKBgQCu22gfszWpKIqMDpndcAdHTPOJt04D56nXcSXBUY4pn48Q97\/R\nHl0+dEeHqoh9Pj5mb0GZHA5aVNhC5G9Zl+3mB\/CZbIQcIVDPOEuVl4OBEoZ\/Y0Rv\n5fYNUPu9X8MnALRd8IghEr2yzmzviIe19OdbmBfIWn4mDOGGhmVgIaUUvQKBgAHw\nXct4\/sFJm5W4vUduT8e34EtSf8JDS8r3aJCQACdl7oEGj3DCH5pCehNBXPtldNxU\nIc2i4iqk8C1uw2dQ71upCsnj99k6xnTYzRPs7Mfonu3pHxoFktOFYV+pXpY0QoIw\nDmTvNKCHbvSekfhXSA3zcblRMnxi1CWqNNzKSe2jAoGARPBS+EZVvC3csYVla6YU\nNcrJiTmyo2KdWwwQFQkjEjXXZkHQU6ao3zJMFyCEWJ1h+EJ3ry1gdMCm6Z0T+Z2j\n69YJnBN3AyUUb+rrpwnL++ZHakD5XUKYWPW+QMWQNOATlUlzW\/4aPIVDRoFExK5x\ncyMghvMdiG8YybtfXMxvkog=\n-----END PRIVATE KEY-----\n",
"algo": 7
},
"3072": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAqZkSqLk+3Do2vFSvaqeR\nr6R620V4WAqEGuZcA\/rhgu6\/YihNKgdBqOyrOyhXoPn\/2pAIa9lCqdHXxxXgMwEs\nBhmHGeFpze\/w91BM36NVVO0BFbM\/Vq4eSZyROO211RA11CNxbuPeWROmG\/bIvAVD\n78Y71ldfq4cCs0I\/SC2U74A8ubsuQ7A1EFVkGp\/PPV3oGJb2eG927rhBIFoyYVZ3\npHLBAI2txuqf8sfGAEnMO3WaFf0lT1\/YP+c4apvqg+dk9XaFbZbNSE1M\/rlqsq\/l\nOgbn+Qi0kmFOuTk1x7beUEMu4VGXsP2ehN4UjR\/P9xuj6FG1+VTNAPPww1RsQgA3\nR2P+PJMkSTaclBsGOnjw0L9TXcNpTXED8Hq0\/66Vif\/9kvUjfhFc1vdhF9dz8nbn\n5d0ygPznCAIdTnrujyAmDFF2OBceZ6DQKmGP8SOTQDLUOnrZ3CzsmsPFlh+YbC8h\nAcwHpicVKwgUgp2OAUcNSWSakpCMCLTgjmpNcWuI1HUrAgMBAAE=\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIG\/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQCpmRKouT7cOja8\nVK9qp5GvpHrbRXhYCoQa5lwD+uGC7r9iKE0qB0Go7Ks7KFeg+f\/akAhr2UKp0dfH\nFeAzASwGGYcZ4WnN7\/D3UEzfo1VU7QEVsz9Wrh5JnJE47bXVEDXUI3Fu495ZE6Yb\n9si8BUPvxjvWV1+rhwKzQj9ILZTvgDy5uy5DsDUQVWQan889XegYlvZ4b3buuEEg\nWjJhVnekcsEAja3G6p\/yx8YAScw7dZoV\/SVPX9g\/5zhqm+qD52T1doVtls1ITUz+\nuWqyr+U6Buf5CLSSYU65OTXHtt5QQy7hUZew\/Z6E3hSNH8\/3G6PoUbX5VM0A8\/DD\nVGxCADdHY\/48kyRJNpyUGwY6ePDQv1Ndw2lNcQPwerT\/rpWJ\/\/2S9SN+EVzW92EX\n13Pydufl3TKA\/OcIAh1Oeu6PICYMUXY4Fx5noNAqYY\/xI5NAMtQ6etncLOyaw8WW\nH5hsLyEBzAemJxUrCBSCnY4BRw1JZJqSkIwItOCOak1xa4jUdSsCAwEAAQKCAYAE\nGV8KFPAgAogwJRvYSBSNWjxd8F\/oQNjQjaDLt9SbhYm6pZ631VUQ8CdzVpZHncNB\nVRnfAXFLCXddqHmyweR+gT9ysLAN+i6oy5gQD7KQSuorzBlLzwmMXexko9oxPCMQ\n7YpgU8GcBY2OP3i6kqYBtZjcpV\/6lVjLXF6LMA7Zew\/8rTmBCVE\/A9FXk2U+5nYl\nogBzCL6nJmzsi0GMeLqLjvp7OPFqTWFwTMPMXfxBs6X1whiUwoxHfx8t9HbGmWEd\nOyNlauPGPIMyRbLHaz6YTp9Uy468SEA5BXBl8op+h7BT8ACBORKIrG\/A0jlU7B8c\nTZniDvJ25RZiXkfR5ucgFCF\/jjOwRUJQ8hPOGRMGBi\/kOMeGYQFnAGbbqnoonbYx\naFpl\/mH+SvpYfS5KKT+YACApUvdADVumKQHaafhxJ+KQi+GVVi5t+r29dsML+1Js\n6Jrzt0kqdCTn+ldEtAXy5hQe\/bOp2cL7SYGvCdvwhbmUXDOTfb6pLe3BuEydKQEC\ngcEA0HFn5M4+A7FzYExLnJIA0SbBq9PZprg41eK6w657w6FD+lTGft4Fz24MgvUN\nH0TSYzDh4oH\/WosPfUKI4uyDEpQ5W13WDhPtEN4h6jw2Qxm048UmOgogNlxRRmtx\nyp1sFITp4yan1DteyKxqADd87mGBGnzz8b4EzcOsFx9KdwwbjfTOFRQCttNhXkr+\nVkwISmxQdqQkxoIwWUXxqqkWBWgHRxN9vxHGmzp9rxurtGDMlu\/osg0SIeIkHlcs\n5rVjAoHBANBK1Qpad9Ay5CigBbGWdKTM0Gp6GkzLRDpXi0bKQMKVLEFwdn4mvzbl\nnnZ0HDF2fWk3GfZdtW7i2uWjorIH5suO3iR9L3KUC5nM7qDnNtH5\/w6SV+YQTHQC\nSoAoVvcAf4kES\/kspghlR5EvHXJShzWW0X1EYcqIBdVL8cEVFUJ4eFUNSF45ckYd\nGI+IVmjfS+aENz5ifyTaQIf2N7fw7Ww5fkJWZRHfiyYD4GT9pbjyqCanHOxr+9mw\nagccYs3PmQKBwQCr0n\/o7VXTZ4iK\/flqJDSGNCN7x9Nnif5X2WFJAuDEv3+wsAc7\n9zrk5XtszCG3\/9xJpbbeJ3jeIzlucNUz8fCN9R9ewHg9\/JDz0Zg1ZNL59wvUoeRD\n\/arWBL1+hf00HxZDx9igxXGdEh+s3es3KIZUXo20zwGr6Y4+K6kFGmcgwRtJpl3m\npCskmBRwTPNhIaXH64dcdSxXcmP2gyCWJHGhnUI6hcenJDkKJmoKWY3tz8l2Nmcj\ntoCW67oIRKYfu68CgcBaFyPSGJMd8AUTNTOBPiwxY4z5oNpjQL+\/5EGPWsdr4g2E\nOFpn8eZeni5N2aagFjnkGjsWfi2NSn2XOZGTIyvF+4NFkQfGrRXfbe4AlkD1zQVu\njgmKrp4Cx0Ll74y9xO9kmgEqQw+FLhkoSJKZ8ewdV6BAaCVL7k1nljN4aeAKIgUZ\n9GbKqloszUTkP\/nv3jT7\/U\/PodaQX\/3tUKeE3aYzWyKrGqcYdfG\/fYm+5J6bQglM\nvpcaAxKpc05IyRRLJHECgcEAyyk404F\/4W4iV5Mg1\/k5YZQ6M0KJsHo1XxdmTKHt\n9JiuA36WeAzUJuUfVNK1YgvLh11a4gEYashnh9teHq7G638GKUYLDu8HOfGw6BFJ\npiBjSCWvScB2xIw4DP8z8Es5nKqgw3inziWWwXrbHJafPatqshEtAJHXKnPw4GhN\nV0CdHfO3rnlPxaL1bHp2v1MEbgN40jXyiTX0TjwNVePInWVm3WE3DjVvoX1qFsI3\n3jqsI9Cam0Rqzpifts6BrbAP\n-----END PRIVATE KEY-----\n",
"algo": 8
},
"4096": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsZgBI+A4oHBTznGyTZlN\ncdHg\/O5q8MKmoTKOXP374oJ6ubzKEEOr4E1RGf+hFOUrPTj9OCnyOJ3K63Dh0hXg\nM2RNOtJzU1upFUozlqxCGaKO69DaDIXwWYSXEaaVkIvWHYtwh8iD35B15lcIG57m\nkIkYloJybZD1W4JBzDObfuoUvLKfYGxGu3CLlDJbhgPH28UAYjMMVknAoMdYJuk6\ncTTMja69HCm5fnH3oQj\/cwkcvfM6J5OhvvUZs7cdHQ1ySG4isMS5ymeMqaOeRKQz\nnkRQYjxys12b+NM+oYih0gQL4kl1Qu\/cUs+xrDlxXj2LvQDnsTg\/KXfgKYhAYYAc\nCBh\/\/LHfFpx0OBUKEIN6D7S4PJLIV3hx6vMJOAFJFF74APZRQy\/4LWYMq3Y4JCiE\nCpwOyBBoceoNUSRziHuEIgb\/1IQWtlDteB7pkUom40u3D2wH+z4+2KFV+Y3yYzFM\nB+ogNm0qt+Kze7v8tKrOgCf1QQZfFq5EgyfAYpB3xT1v+dpURiq4d3rDeDFzm+47\nH7tXrrTYzbEIaI4Ow1ukCcfAFGWobj4\/DIs\/QOFhi9x+MXT9CIR1MlsGAIUIrhpK\nYapVkpMO5z3xyzNpJ6FvkSIhnqRAPt0FG5cfOtuQdVgWvvhjuB+0ALTPFCEFe1uR\nka2V981W+HJ\/WqgcVVR7Y3cCAwEAAQ==\n-----END PUBLIC KEY-----\n",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCxmAEj4DigcFPO\ncbJNmU1x0eD87mrwwqahMo5c\/fvignq5vMoQQ6vgTVEZ\/6EU5Ss9OP04KfI4ncrr\ncOHSFeAzZE060nNTW6kVSjOWrEIZoo7r0NoMhfBZhJcRppWQi9Ydi3CHyIPfkHXm\nVwgbnuaQiRiWgnJtkPVbgkHMM5t+6hS8sp9gbEa7cIuUMluGA8fbxQBiMwxWScCg\nx1gm6TpxNMyNrr0cKbl+cfehCP9zCRy98zonk6G+9Rmztx0dDXJIbiKwxLnKZ4yp\no55EpDOeRFBiPHKzXZv40z6hiKHSBAviSXVC79xSz7GsOXFePYu9AOexOD8pd+Ap\niEBhgBwIGH\/8sd8WnHQ4FQoQg3oPtLg8kshXeHHq8wk4AUkUXvgA9lFDL\/gtZgyr\ndjgkKIQKnA7IEGhx6g1RJHOIe4QiBv\/UhBa2UO14HumRSibjS7cPbAf7Pj7YoVX5\njfJjMUwH6iA2bSq34rN7u\/y0qs6AJ\/VBBl8WrkSDJ8BikHfFPW\/52lRGKrh3esN4\nMXOb7jsfu1eutNjNsQhojg7DW6QJx8AUZahuPj8Miz9A4WGL3H4xdP0IhHUyWwYA\nhQiuGkphqlWSkw7nPfHLM2knoW+RIiGepEA+3QUblx8625B1WBa++GO4H7QAtM8U\nIQV7W5GRrZX3zVb4cn9aqBxVVHtjdwIDAQABAoICACCpsc\/83b1YW3mVPLN79hvw\ne35ZhU6ppkbwivF8fxa+Y78Eg29xWsvCvJ9Y\/jHfIlA8yonJYTTbhKY\/2TCv+E\/L\na07dxPs4WQVC4\/Ea1n9rf\/jMLUZvXfDA654B8vEmXueJLVWz4dk88wo9yI5377T2\nmhCYhl4zcoT1lI9vkHJLsCuyeJCd6XZw8SL9Dgs8Z8Y6WeM1u1elcenAMCzb6XVH\nvjVyxXJIFEc2w9IY2w63xtMCyJfd1bpOzv7YN2EQB4xdwUCctgUNfXf30VSTlLDP\npK8kqf3mQhkGFTdVb1m2h88DLq90eSO78lQYLoskK67D21kjXK6OTyqkVh74lm7x\n8toWEmIs6EQ5L3VAcAaeoanULojid9rb2YnOSNq8NwBKVfNqK\/rrrwyhnBwW8Co3\nyNi5Q1EdsXUoRVowd0L8+NvBhc\/D9PZqm+kiMF2q3zBcLFol\/amO2ABMsBPxbcqD\niL7FlyLLJLd5lwXxyEz1Xq6olhmHiqNn7SSCSEDVYB1MofxXg5dmE7IbjP3G4Kxj\nF+4INrcjj89vUsy9wadhTV1sBU\/n76HU5i88JS34nIdJQIsb7Pm4vqee9EuljdI5\n73sXX5a6WvZGE+Hu4KqWbk2nonJF9dpxn9VR4mVQmxSHtWjkzNXtCzOl\/QFyp+GM\nto9IFsIis3qQB\/OJ54mxAoIBAQDqwVgiqxfgcv0I7Pfb+VXCvezteZpuAVTsxWSZ\nbzgkVu7ZXwFwra\/VaaNRhWM7u8DSvEc87wLOO2PRB9vPSFJKRX53qbUWrlBD0s2a\nOiSnBnRUCW9UB08YgBMiCzviqPOwyfQ5QYSOJBeU02YRT1IEgX\/YbOzzp7MPFtkk\nyuG1NQGTreqQs1z7M\/xTLG4krIEzY5xa75I+NSmNBud0hgqe\/5gDEewsX+uGF3dm\nkL3P5uglbpLW\/uFuqRuY5h9oRhRADQh7WoSkn4gegOKyVQEzhra5zCMLViRriW\/v\nVUyBC8dnDRuOJ7vrwqHMyb2n6Iwbg2+H9GiMKCpeYbaYM0SnAoIBAQDBqmFiF8Y2\nUcPLGSsiV1zlN8w+2vGmGnTVscDz+u2s0wjYismWRVEhWNPyLVFN4UsdalJ7JFgN\nzQubePXKai\/hLTjDUink0e2TUQx4TQBUU21OXxHA6WukGBZXrP0d0KXRjzbShemN\nTIeKaNox2NWEQUJWKpzkeyEm+d+Tpsp1CtbfeiD+XQMZr\/QuEcyXaenLj1WJX8oa\nRZAs33YzSrN\/WOZ2xTEyympmJC8p0upoPxAu+CrYCIJZ\/9cHruvkzJD1j95seZAE\n2TsbEC0sTQE3h8HpHQWFPi4CR9vQQVXza35qlvZnT1yxJwXOX6AEce9aXHFiHANg\nCRwZt\/7gETSxAoIBAETHSsw1dnRjHDF+RAwl2\/OHc6AL7avnJfuMxbGSfU9gTPBQ\nvnpF2Otc3OWof+9jTdYwJWr718WWbuMyOztaxAlQnQHwLccsYQXOAED8YfqxkGmC\nriRfU9QoyfJCelQpDeSw9qXDxVNjzajj2tadd7ksO8mr+CxW6MY1+n6mFkTh98lN\nvhiRBF\/w1i+EJ+0EwYHN4GRgJmelabwQ1sUz9G6rEd1sZdaGb9nEjE33gDUmQMOe\nxtTIrkGeuCAu4+rIBWzSpLaHSa91sgrF1iVLdGOlR2neHjJXFaqQBMSJKDXyvoQ5\nueYHTC6BwqfeP3uvTUVOV+HsQKk3p1oppLao5qcCggEAKJHpvqPeWQi97HEEUThd\n9ILA3bX+A17tdMq88h9x5M98vegtHLa+rS6vj78gliEJHEtmpfdSHuoCcXpgexvN\nle1kQ76VmiLEEyVaaGUxGXk0n8NYs8HyU7jcDVfm2nUYF5NZ17ZH29rZVgxrESAs\ncn09SVG59j85DbIwvPym0ugHZV9vQ\/n2KU5r567A3kNIv+Tx9UpEy0YhUtUpLMuM\nWLQl62GZ0dsHeQhBfRB7HIWBfWVtjD4UGIh44lopfo\/AGkEeRjkdC3b6Y8v6upoT\nFC\/zVkNHIceJ2d511OWq\/Mha\/jdLvQ6qC05yb+4mVmgLzTEqa3QU3Oxrn5Ok6AmS\nsQKCAQEAhQ+lmWkp0qmLEJpYeX8Ct14NGPEEeUs8v\/0AIzkYvMFMoRsXqnVwmAko\nyVu+szQiV\/4SIet6UF53TyGaBJ15EfZAorOfWdMTlvO5Iz7hpTe\/9z5W7tuk4iGR\npcxUYKc3tJg9Yp5M6y2lWzLVUHtc\/2LiP1OUAxeDDmhhYSR7MIiuIg5yKAYbW04B\navIh+uDEjO2iv5jWrtBBpCAPSzBOX5qRFSbs419dnpmpatPY4hPMSNyOQCfBEScL\nr6fcsDq19iUgP2tu9GGIotwbw0kpaTtwvl+i\/kxeNmPAx7zK2evuXfp1Gue4jsoa\nB+4qZpx1tNgmByE6xwy1BX7GmcYu8Q==\n-----END PRIVATE KEY-----\n",
"algo": 9
}
}
}
Loading
Loading