Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement TimeStamping feature #617

Open
wants to merge 44 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
28c747b
Update tcpdf.php
hidasw May 14, 2023
ff9e5a8
Create asn1_function_tcpdf.php
hidasw May 14, 2023
ff20f9f
Create asn1_parser_tcpdf.php
hidasw May 14, 2023
e998624
Create functionLog_tcpdf.php
hidasw May 14, 2023
ffce574
Create Local Root CA.crt
hidasw May 14, 2023
15bf870
Create tcpdf test.pem
hidasw May 14, 2023
a295943
Create index.php
hidasw May 14, 2023
abfaeda
Update tcpdf.php
hidasw May 15, 2023
01fb957
Update index.php
hidasw May 15, 2023
1656d3c
reformatting and cleanup
hidasw May 16, 2023
80f70d3
Update tcpdf_asn1.min.php
hidasw May 17, 2023
3ab497a
Update tcpdf.php
hidasw May 17, 2023
c8e4c7b
major update
hidasw May 25, 2023
c16b58c
Update tcpdf.php
hidasw Jun 4, 2023
f1de348
Update include/tcpdf_cmssignature.php
hidasw Dec 22, 2023
1499b2b
Remove type on properties.
evamtinez Apr 16, 2024
df74f95
Curl close was moved after curl_getinfo.
evamtinez Apr 16, 2024
4a384cb
Fix indentation
evamtinez Apr 16, 2024
fe6c482
Merge pull request #2 from evamtinez/main
hidasw Apr 18, 2024
3a741b6
Add TSA parameter
hidasw Apr 19, 2024
fe247a1
update to support LTV and TSA at once
hidasw Apr 22, 2024
050eec1
Merge branch 'main' into main
hidasw Apr 22, 2024
92f3539
significant improvement on signing process
hidasw Apr 24, 2024
3ecc5ab
Merge branch 'main' of https://github.com/hidasw/TCPDF
hidasw Apr 24, 2024
959052d
combines several functions
hidasw Apr 24, 2024
9950510
Update example_052.php
hidasw Apr 24, 2024
e1297c2
Update tcpdf.php
hidasw May 14, 2024
a7b5ebc
Update tcpdf_cmssignature.php
hidasw May 14, 2024
46ecd34
Update example_052.php
hidasw May 14, 2024
6ab1ed7
Delete RootCATest.pem.crl
hidasw May 14, 2024
f166179
Delete RootCATest.der.crl
hidasw May 14, 2024
f7dc852
Delete Root CA Test.crt
hidasw May 14, 2024
7a766b6
Delete Root CA Test OCSP Signer.pem
hidasw May 14, 2024
2543e57
Delete PDF User.pem
hidasw May 14, 2024
0913f4f
Create PDF Signing CA.crt
hidasw May 14, 2024
58228d7
Create ocspTest.bat
hidasw May 14, 2024
5ea1de8
Create longChain.pfx
hidasw May 14, 2024
d2f6c24
Create longChain.pem
hidasw May 14, 2024
ca7a5e3
Create long.pfx
hidasw May 14, 2024
67ce271
Create b6ce4782.0
hidasw May 14, 2024
42beeea
Create 7262ea48.0
hidasw May 14, 2024
0884ea0
Create 71ab782e.0
hidasw May 14, 2024
5d1c8ec
Create 5a0ce691.0
hidasw May 14, 2024
cbb1aac
Create 26a91b3f.0
hidasw May 14, 2024
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
43 changes: 43 additions & 0 deletions include/asn1_function_tcpdf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
// change at 22:37 Sore 04/09/2009
// change at 16:04 Sore 14/05/2023
function asn1_header($str) {
$len = strlen($str)/2;
$ret = dechex($len);
if(strlen($ret)%2 != 0) {
$ret = "0$ret";
}

$headerLength = strlen($ret)/2;
if($len > 127) {
$ret = "8".$headerLength.$ret;
}
return $ret;
}

function SEQ($hex) {
$ret = "30".asn1_header($hex).$hex;
return $ret;
}
function OCT($hex) {
$ret = "04".asn1_header($hex).$hex;
return $ret;
}
function INT($int) {
if(strlen($int)%2 != 0) {
$int = "0$int";
}
$int = "$int";
$ret = "02".asn1_header($int).$int;
return $ret;
}
function SET($hex) {
$ret = "31".asn1_header($hex).$hex;
return $ret;
}
//function EXPLICIT($num="0", $hex) {
function EXPLICIT($num, $hex) {
$ret = "a$num".asn1_header($hex).$hex;
return $ret;
}
?>
73 changes: 73 additions & 0 deletions include/asn1_parser_tcpdf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
// ASN.1 Parser start 21:31 Sore Kamis 26 Maret 2009
// ASN.1 Parser at 22:10 Sore Kamis 26 Maret 2009 Telah jadi utk standar asn.1
//
// 06:40 Esuk Jumat 27 Maret 2009 ASN.1 Parser kesulitan dlm memecahkan explicit > 9

// 11:18 Esuk Jumat 27 Maret 2009 parse explicit:xx mulai dipecahkan. kemungkinan tlh jadi
// 17:51 Sore Jumat 27 Maret 2009 memecahkan explicit sampai 2097151 (65536 * 32) kurang 1

// 20:04 Sore Jumat 27 Maret 2009 ASN.1 Parser tlh jadi. Congratulation....
function asn1_first($hex) {
$asn1_Id = substr($hex, 0, 2);
$header = substr($hex, 2, 2);
if($asn1_Id == 'bf') {
if(hexdec($header) > 128) {
$headerLength = hexdec(substr($hex, 6, 2));
$reduced = 8; // the string reduced by id & headerLength
$expNum = (128*(hexdec($header)-128))+hexdec(substr($hex, 4, 2));
$header2 = substr($hex, 4, 2);
if(hexdec($header2) >= 128) {
$headerLength = hexdec(substr($hex, 8, 2));
$reduced = 10;
$expNum = (16384*(hexdec($header)-128))+(128*(hexdec($header2)-128))+hexdec(substr($hex, 6, 2));
}
} else {
$headerLength = hexdec(substr($hex, 4, 2));
$reduced = 6;
$expNum = hexdec(substr($hex, 2, 2));
}
$asn1_Id = "EXP:"."$expNum";
} else {
//echo "$header==";
if($header == '83') {
$headerLength = hexdec(substr($hex, 4, 6));
$reduced = 10;
} elseif ($header == '82') {
$headerLength = hexdec(substr($hex, 4, 4));
$reduced = 8;
} elseif ($header == '81') {
$headerLength = hexdec(substr($hex, 4, 2));
$reduced = 6;
} else {
$l=0;
$l = hexdec(substr($hex, 2, 2));
$headerLength = $l;
$reduced = 4;
//echo "$headerLength --".substr($hex, 2, 2)."--<br>";

}
}
$str_remains = substr($hex, $reduced+($headerLength*2));
$content = substr($hex, $reduced, $headerLength*2);
$return['res'] = array($asn1_Id, $content); // array 0=>iD(sequence be 30, integer be 02, etc) 1=>contents of id
$return['rem'] = $str_remains; // the remain string returned
if($str_remains == '' && $content == '') { // if remains string was empty & contents also empty, function return FALSE
$return = false;
}
return $return;
}

function asn1parse($hex) {
//$return =false;
while(asn1_first($hex) != false) { // while asn1_first() still return string
$r = asn1_first($hex);
$return[] = array($r['res'][0],$r['res'][1]);
$hex = $r['rem']; // $hex now be result of asn1_first()
}
if(!is_array(@$return)) {
return false;
}
return $return;
}
?>
49 changes: 49 additions & 0 deletions include/functionLog_tcpdf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
// create 11:16 AM 10/17/2011
function tsaLog($str, $type = 'i', $nl=true) { // 11:16 AM 10/17/2011
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file and function should be removed from this pull-request

Copy link
Author

Choose a reason for hiding this comment

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

yes it for debug only

$dateFormat = date("D M d Y H:i:s");
switch($type) {
case 'e' : $errType = 'error'; break;
case 'w' : $errType = 'warning'; break;
case 'i' : $errType = 'info'; break;
case 'n' : $errType = 'info'; break;
default : $errType = 'notice';
}
$clientIpAddress = $_SERVER['REMOTE_ADDR'];
$clientHostName = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if($clientHostName == $clientIpAddress) {
$clientHostName = 'unknownHost';
}

$prependLog = "[$dateFormat] [$errType] [client $clientHostName ($clientIpAddress)]";
$explodeStr = explode("\n", $str);
$prependLogLen = strlen($prependLog);
$prependLogIdent = str_repeat(' ', $prependLogLen+1);
$newLine = false;
if($nl) {
$newLine = "\r\n";
}
$strLog = false;
foreach($explodeStr as $lineNum=>$strLine) {
if($lineNum == 0) {
$strLog .= rtrim($strLine)."\r\n";
} else {
$strLog .= $prependLogIdent.rtrim($strLine).$newLine;
}
}
$log = "$prependLog $strLog";
if(is_writable(getcwd().'/tcpdf_tsa.log')) {
$handle = fopen(getcwd().'/tcpdf_tsa.log', 'a');
fwrite($handle, $log);
fclose($handle);
} else {
$handle = @fopen(getcwd().'/tcpdf_tsa.log', 'a');
fwrite($handle, $log);
fclose($handle);
if($type == 'e') {
echo "<pre>\nCan't write log to file \"hdaLogs.log\", please check file permission. hdaLog return error, these error is:\n";
echo "$log\n</pre>";
}
}
}
?>
93 changes: 90 additions & 3 deletions tcpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,8 @@ class TCPDF {
* @protected
* @since 4.6.005 (2009-04-24)
*/
protected $signature_max_length = 11742;
Copy link
Author

Choose a reason for hiding this comment

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

i''m increasing this size to provide enough space to place tsa response data. and sometimes need more, depend on tsa response data size.

// protected $signature_max_length = 11742;
protected $signature_max_length = 20742;

/**
* Data for digital signature appearance.
Expand Down Expand Up @@ -7692,12 +7693,14 @@ public function Output($name='doc.pdf', $dest='I') {
$signature = $tmparr[1];
// decode signature
$signature = base64_decode(trim($signature));
// add TSA timestamp to signature
$signature = $this->applyTSA($signature);
// convert signature to hex
$signature = current(unpack('H*', $signature));
Copy link
Author

Choose a reason for hiding this comment

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

should before $this->applyTSA($signature)

// add TSA timestamp to signature
$signature = $this->applyTSA($signature);

$signature = str_pad($signature, $this->signature_max_length, '0');
// Add signature to the document

$this->buffer = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]);
$this->bufferlen = strlen($this->buffer);
}
Expand Down Expand Up @@ -13675,6 +13678,90 @@ protected function applyTSA($signature) {
return $signature;
}
//@TODO: implement this feature
// start timestamping
// by Hida since 5.9.128 (2011-10-06)
if($this->tsa_timestamp) {
//Include asn1 fuction script
require_once(dirname(__FILE__).'/include/asn1_parser_tcpdf.php');
require_once(dirname(__FILE__).'/include/asn1_function_tcpdf.php');
require_once(dirname(__FILE__).'/include/functionLog_tcpdf.php');

$tsaLog = __FILE__." line:(".__LINE__."). Perform timestamping...\n";
//Parse TCPDF Signature structure to get signed hash sequence
$p = asn1parse($signature);
$p1 = asn1parse($p[0][1]);
$p2 = asn1parse($p1[1][1]);
$p3 = asn1parse($p2[0][1]);
$p2 = asn1parse($p3[4][1]);
$pa1 = asn1parse($p2[0][1]);
$pa2 = asn1parse($pa1[3][1]);

//Create timestamp request

//Create hash of encrypted contents TCPDF signature
$hash = hash('sha1', hex2bin($pa1[5][1]));
//Build timestamp request data
$tsReqData = seq(
int(1).
seq(
seq(
"06052B0E03021A". // Obj_sha1
"0500" // Null
).
oct($hash)
).
int(hash('crc32', rand())).
'0101ff'
);
$raw_data = hex2bin($tsReqData);

//Send request to TSA Server with Curl
if(extension_loaded('curl')) {
$tsaLog .= __FILE__." line:(".__LINE__."). Curl was already Loaded\n".__FILE__." line:(".__LINE__."). Curl is sending tsRequest to \"".$this->tsa_data['tsa_host']."\" ...\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->tsa_data['tsa_host']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERAGENT, '1');
curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_data);

$tsResponse = curl_exec($ch);
if($tsResponse != false) {
$tsaLog .= __FILE__." line:(".__LINE__."). tsRequest is sent.\n";
} else {
tsaLog("$tsaLog".__FILE__." line:(".__LINE__."). can't send tsRequest, Timestamp failed!\n",'w');
}
//parse ts response
$hexTs = bin2hex($tsResponse);
$tsparse = asn1parse($hexTs);

$tsparse0 = asn1parse($tsparse[0][1]);
if(count($tsparse0) > 1) { //Remove response status data, only take timeStampToken
$timeStamp = seq($tsparse0[1][1]);
} else {
$timeStamp = seq($tsparse0[0][1]);
}

//Add timestamp to TCPDF Signature
$timeStamp = seq("060B2A864886F70D010910020E".set($timeStamp));
$pkcs7 = int($pa1[0][1]).seq($pa1[1][1]).seq($pa1[2][1]).explicit(0, $pa1[3][1]).seq($pa1[4][1]).oct($pa1[5][1]);
$time = seq($pkcs7.explicit(1,$timeStamp));
$aa=seq(int(1). set($p3[1][1]).seq($p3[2][1]).explicit(0, $p3[3][1]).set($time));
$hdaSignature = seq("06092A864886F70D010702".explicit(0,($aa)))."0000";

$signature = $hdaSignature;
// $tsaLog .= $signature;
tsaLog("$tsaLog".__FILE__." line:(".__LINE__."). Timestamp Success.\n");
} else {
$tsaLog .= __FILE__." line:(".__LINE__."). Curl was not loaded, trying to load it...\n";
if(@dl('php_curl.dll')) {
$tsaLog .= __FILE__." line:(".__LINE__."). Curl successfully Loaded.\n";
} else {
tsaLog("$tsaLog\n".__FILE__." line:(".__LINE__."). Curl failed to load. Timestamping failed!", 'w');
}
}
}
// end timestamping
return $signature;
}

Expand Down
32 changes: 32 additions & 0 deletions test/cert/Local Root CA.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFfDCCA2SgAwIBAgIBCjANBgkqhkiG9w0BAQUFADBNMRYwFAYDVQQDEw1Mb2Nh
bCBSb290IENBMREwDwYDVQQKEwhteSwgT3JnLjEgMB4GA1UECxMXbXlzIFRydXN0
IFdvcmsgU2VjdXJpdHkwIhgPMjAyMzA1MTMxODI2NTdaGA8yMDYzMDUxMzE4MjY1
N1owTTEWMBQGA1UEAxMNTG9jYWwgUm9vdCBDQTERMA8GA1UEChMIbXksIE9yZy4x
IDAeBgNVBAsTF215cyBUcnVzdCBXb3JrIFNlY3VyaXR5MIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAlKoSYfMP1Jcx3Qzb3e7tb03LAPPhVVzJRVdWfp7/
mtwz/cPEu4xlNARHgAPRFwg8RhM1QGsqpNyD7mBr3r5BNjbd2RZK6xyq7nJ8kYfp
OBEZaFHcpmOLU2IFU04r9lkcnymr2hkB2uXxOZt15U86YCIf4bFqiWLvgK10ID6f
a1tXko1/oF9P3YNyVoSdGvBbAZv/jl8MV/yW5QZQ7qvQosteZFsMd7ZDWmb1Pzrm
t/Cz1G+Kt/XwpQIbYSHCmjam8EywN4yWutN8XqRxDa31jCyByfSsUdNjzexok9u0
EiWe0qxs67Ke23j05D01ojtPJtdos9Pg7gaviClfnHi9Kc47WREsecusNQLn918v
W+oQ+iTJcEqiK2Hrkv3w96s6fkDuTeEePJOHh1pGTwM+bS2u1luBlooMuje4uoPr
XRBSQK9SuhFU0CTpz5Kao0OWb4LdRHYuJkLmrLlAXBp9lYXFLEFA3++QoN9/LH9h
Rx2+M192qV21hpGF7RVIHftwvs0IHAfZSQvkSOl/FBAKQEf5+TffZpxIZtay/616
IOpNo91XGPM9eCR1OSMJjt3wM9WTuQ0m4cMAjSmwbChi/+e5yr+K/jxfEq3XHG4i
S+uMBbFEVB+4hJAlZIQlK1rYFeJGVZ7Ld4x3DappPfW3Z8rUz1Q24Ydr9BflPUmK
U/MCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQWf2Ctaq5aZnWZ
IScx6z0KK4DFuDAfBgNVHSMEGDAWgBQWf2Ctaq5aZnWZIScx6z0KK4DFuDAPBgNV
HRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCA3MxJHqOk6b/Nr+YpczLQ
24QOa3HCYmaPax1FcgX075Z4XgawwCuam7nFdJIf351OX8EJlvQA3X0Hsyd70im6
v5o3h4qRaeiRxEhZcp48mbCg8ZDWO2y4MkWO+DZAYFupAeZExhbneMgwdRQwUzVx
Gv6I4ms0NvJbd99iCBEtGeoAZmgCr9lz7WVGJYFeBL6SNhU+m03/1o1n2HUWn+Im
va4SDR/FTICMd5PfCioLuE3/OrqbYo5E04QmwNdBufpBQvbxohnDHIVFqjSOaAn7
glwGuJjKShEYh0BoRuwR6cN85GcgR0SgwJPMiidSQ/e+0UeEm2CmQBuN4VWo/LIq
kBT1f7p4xLRdiSTLRK6vMkTn0SlzNtc8axI9ilWDQgVGoHc7BmGK1UZGsVDXyCGj
RguxBBYvS+hrKzym/AmBLW3qlHysoL2XgoPMZ3d6jrsY8HVcLNcrL2OG5DNN96sM
K1BaMuJex5IATxMwUOsHm80XY6x13uvIXfq0NoHH0rKNcaHVTDdVEQ9j3tUgLQe2
hjBteYgJhH6W75sTQL99KxDTx0Jx9XtQMqgGswSHVmUm/ASy40C+31qH7MSd3Gxy
awXE23azjNjt8nUKXZpbweTGh1MixMgTckukuIFW8/oGPQHIQg51BfV5BdNxPDr/
Fk0KsWn7PB5XeB86nKHGmA==
-----END CERTIFICATE-----
42 changes: 42 additions & 0 deletions test/cert/tcpdf test.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-----BEGIN CERTIFICATE-----
MIIETzCCAjegAwIBAgICCgMwDQYJKoZIhvcNAQENBQAwTTEWMBQGA1UEAxMNTG9j
YWwgUm9vdCBDQTERMA8GA1UEChMIbXksIE9yZy4xIDAeBgNVBAsTF215cyBUcnVz
dCBXb3JrIFNlY3VyaXR5MCIYDzIwMjMwNTE0MDkxNDQ2WhgPMjAzMzA1MTQwOTE0
NDZaMHMxIDAeBgNVBAsTF215cyBUcnVzdCBXb3JrIFNlY3VyaXR5MScwJQYDVQQL
Ex5UZXJtcyBvZiB1c2UgYXQgLm5ldC9ycGEgKGMpMDkxETAPBgNVBAoTCG15LCBP
cmcuMRMwEQYDVQQDEwp0Y3BkZiB0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQDQPsTVI4Wl+tP6FuhDCsmtN/d9bGvmHSl3c/9r+7zeQF0NHWlUihWV9FCS
vfFYFXfmoW8gaU27/rHEOH80rDB/+XAujNFosR4WMpsINcxG9r1jBsNYhz08mCk/
vsiTUGdS2u1eZN3c57tW9Xk5xrIFmoViZm2gpmP7z8CYC5O81wIDAQABo4GSMIGP
MB0GA1UdDgQWBBQQyvU+J2WBqtm3OIhnLmgTONsqCjAfBgNVHSMEGDAWgBQWf2Ct
aq5aZnWZIScx6z0KK4DFuDA/BggrBgEFBQcBAQQzMDEwLwYIKwYBBQUHMAKGI2h0
dHA6Ly9sb2NhbGhvc3QvY2EvTG9jYWxSb290Q0EuY3J0MAwGA1UdEwEB/wQCMAAw
DQYJKoZIhvcNAQENBQADggIBAEpp0GANInY9Pi7oKhJNaM4sfT7DuIm0cKbux3SF
akNEeAg3LHEvfq+ucjWOwWvQujCOrQ3rUSd5WJomtbE0SByTCvAj8Xg4BeCvhMBj
3V/wTKGHew8Y+KoBjuztuwxZ3F00GWKBCxzU+wqPHLcfeWcumPLZksE0mz0h/7uo
AZy1EOyrvUK2RnJuU2GN+9M5trcyibwcCZGV4d/TROXHeFt90vCWS8EL+YNaVSO9
JNWUw1Y2bZUWOXnT6RPO6Qcs8sCn/A6rTK3y/SV11nL+9AcsKr2JBYTWwQjDyEAm
8LjiSde3FoRpVyulRV1V2B14ALv0hIUJpoIWM2nObi+dF7VrXEDn/7RTVd7xjwjB
bfyJmArbhOtKSX4ifDgR1rQQBV1YIgA/zVFxtiYBH3pj4LRSuzm4axIqz4o2B/95
EMjF1xLLk04J9rtj0SSckIxhQoO89I2z9s7LIVliZFKgpKBIvlrAc26+/J+xxYY3
6HwlkgTY1aHUjuJVUqXtp3pZp5aRNjqBZ1Ucy0f0Mec8n5NodzH1RgIylEjDiNsS
ez2DlnxHIatyaa4PkyovzTjS47K3u9dBVyjKPpcWv8ZDIWMcepQcUI58ezXHCkwo
LPzm+Q5tblU1I7bjMqvZeW54+LrRqUq4+HsPe4tP7VSV7YBMLByCzKkQ+OpbhTaN
FQCb
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANA+xNUjhaX60/oW
6EMKya03931sa+YdKXdz/2v7vN5AXQ0daVSKFZX0UJK98VgVd+ahbyBpTbv+scQ4
fzSsMH/5cC6M0WixHhYymwg1zEb2vWMGw1iHPTyYKT++yJNQZ1La7V5k3dznu1b1
eTnGsgWahWJmbaCmY/vPwJgLk7zXAgMBAAECgYBD3zFoBlvY7ReJu02YDDwPKN6R
EnVYWsjZFgV5vGKiTXgGfj+GPjsq1KYuLZori1O454TAm5GqZCisO326PSTQ+hfs
VJpYOuTmwoMKG7aW73wyZzOaTwz5Ju2n99YFjUEcQvy67MRmZXBc0Vu3J3Wb8CTH
F9fgNgHlYKAHGKegAQJBAPlRMm/abDeQ471kW81cGabqwd7Z2C2ys2MhxOqZMbq+
cZcT8ZrKd8MmcgowFTDaEla0BqS+spCSnZUOaulTaQECQQDV07zftpe85M/N4ZKJ
B3GyirJfpHMWJWFGNL+a33LNw/7wU2jXH6E82qr8ojWdK1NEk4ZeLA2PLUbN5zOM
sY3XAkEApfltF1OUiWVWh2XBS7RNi3ZrPB1QMhPuIkd/3SHBHm3cFtR7Gi5BjlQQ
xUF/SfdTEA9nANPG8kH40Bs6Bzy1AQJABtXY8NHWcexilDNEyuqZANscLqCEKU4S
mPrwsRO5iMheKvKPpGjXb6mR07efvSF4bPXGUtZXrJ8G52gfpry6SwJBAPaTOx0V
n7a9tTKJDgF2RL2YbBUUQzmjXlHa8NzcG55GSmTgvjhhKnncmm6s5Slw0WQruB10
fh36J+34k5ZQIyM=
-----END PRIVATE KEY-----
Loading