PHP WebShell

Текущая директория: /var/www/bitcardoApp

Просмотр файла: save_keycard_and_print.php

<?php
/**
 * save_keycard_and_print.php
 * One step:
 *  - Fetch your TRON wallet (mainnet) from BitGo Express on 127.0.0.1:3081
 *  - Fetch the 3 keychains (user / backup / bitgo)
 *  - Save a printable HTML KeyCard (includes encrypted user private key)
 *  - Print your exact summary lines
 *
 * NOTE: This reads sensitive info. Run on the same host as Express.
 *       After use, store the KeyCard offline and rotate any secrets you pasted.
 */

date_default_timezone_set('Africa/Lagos'); // GMT+1

// ====== FILL THESE 3 VALUES ======
$BITGO_ACCESS_TOKEN = 'v2x47b80e4e874e1af4a227a13bbfc2b3c2684db6eafd1c3739e9f3f01cb0b57be2';
$WALLET_ID          = '68bacb35a8cee6d614f8353dec449a39';
$BITGO_EXPRESS_BASE = 'http://127.0.0.1:3081/api/v2'; // Express you started on 3081
// =================================

$COIN = 'trx'; // mainnet
$KEYCARD_DIR = __DIR__ . '/keycards';
if (!is_dir($KEYCARD_DIR)) { mkdir($KEYCARD_DIR, 0700, true); }

// ---- helpers ----
function http_get_json($url, $token) {
  $ch = curl_init($url);
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
      'Accept: application/json',
      'Authorization: Bearer ' . $token,
    ],
    CURLOPT_TIMEOUT        => 20,
  ]);
  $resp = curl_exec($ch);
  if ($resp === false) { $err = curl_error($ch); curl_close($ch); throw new Exception("HTTP request failed: $err"); }
  $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  if ($code < 200 || $code >= 300) { throw new Exception("HTTP $code: $resp"); }
  return json_decode($resp, true);
}
function safe($v) { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
function gmt_offset_label(DateTime $dt) {
  $offset = (int)$dt->getOffset(); $sign = $offset >= 0 ? '+' : '-';
  $h = (string) floor(abs($offset)/3600);
  $m = str_pad((string) ((abs($offset)%3600)/60), 2, '0', STR_PAD_LEFT);
  return "GMT{$sign}{$h}" . ($m !== '00' ? ":{$m}" : "");
}

// ---- 1) Fetch wallet ----
$walletUrl = rtrim($BITGO_EXPRESS_BASE, '/') . "/$COIN/wallet/$WALLET_ID";
$wallet = http_get_json($walletUrl, $BITGO_ACCESS_TOKEN);

$label       = $wallet['label']          ?? '';
$walletId    = $wallet['id']             ?? $WALLET_ID;
$coin        = $wallet['coin']           ?? $COIN;
$receiveAddr = $wallet['receiveAddress']['address'] ?? ($wallet['receiveAddress'] ?? '');
$permissions = $wallet['permissions']    ?? [];
$createdRaw  = $wallet['createDate'] ?? ($wallet['created'] ?? ($wallet['ctime'] ?? null));
$created     = null;
try {
  $createdUtc = $createdRaw ? new DateTime($createdRaw, new DateTimeZone('UTC')) : new DateTime('now', new DateTimeZone('UTC'));
  $createdUtc->setTimezone(new DateTimeZone('Africa/Lagos'));
  $created = $createdUtc;
} catch (Exception $e) {
  $created = new DateTime('now', new DateTimeZone('Africa/Lagos'));
}

// keys array can be 'keys' (ids) or 'keyIds'
$keyIds = $wallet['keys'] ?? ($wallet['keyIds'] ?? []);
if (count($keyIds) < 3) {
  throw new Exception("Unexpected: wallet keys missing; got " . json_encode($keyIds));
}

// ---- 2) Fetch keychains ----
$getKey = function($keyId) use ($BITGO_EXPRESS_BASE, $COIN, $BITGO_ACCESS_TOKEN) {
  $url = rtrim($BITGO_EXPRESS_BASE, '/') . "/$COIN/key/$keyId";
  return http_get_json($url, $BITGO_ACCESS_TOKEN);
};
$keyA = $getKey($keyIds[0]);
$keyB = $getKey($keyIds[1]);
$keyC = $getKey($keyIds[2]);

// classify: user has encryptedXprv or encryptedPrv; bitgo has isBitGo=true; backup is the remaining one
$keys = [$keyA, $keyB, $keyC];
$userKey = $bitgoKey = $backupKey = null;
foreach ($keys as $k) {
  $isBitGo = !empty($k['isBitGo']);
  $hasEnc  = isset($k['encryptedXprv']) || isset($k['encryptedPrv']);
  if ($isBitGo) { $bitgoKey = $k; continue; }
  if ($hasEnc && !$userKey) { $userKey = $k; continue; }
}
foreach ($keys as $k) {
  if ($k !== $bitgoKey && $k !== $userKey) { $backupKey = $k; break; }
}
if (!$userKey || !$backupKey || !$bitgoKey) {
  throw new Exception("Could not classify keychains properly. Raw keys: " . json_encode($keys));
}

$userXpub   = $userKey['xpub'] ?? '';
$userEncPrv = $userKey['encryptedXprv'] ?? ($userKey['encryptedPrv'] ?? '');
$backupXpub = $backupKey['xpub'] ?? '';
$backupProv = $backupKey['provider'] ?? ($backupKey['source'] ?? 'local');
$bitgoXpub  = $bitgoKey['xpub'] ?? '';

// ---- 3) Save KeyCard (HTML) ----
$keycardFileName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $label ?: 'Wallet') . '_KeyCard_' . date('Ymd_His') . '.html';
$keycardPath     = $KEYCARD_DIR . DIRECTORY_SEPARATOR . $keycardFileName;

$html = "<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='utf-8'>
  <title>KeyCard – " . safe($label) . "</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <style>
    body { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace; line-height: 1.35; padding: 24px; }
    .box { border: 1px solid #999; border-radius: 6px; padding: 16px; margin: 16px 0; background: #fafafa; }
    .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
    .muted { color: #555; font-size: 0.92em; }
    code { white-space: pre-wrap; word-break: break-word; }
    @media print { body { padding:0; } .no-print { display:none; } }
  </style>
</head>
<body>
  <h1>KeyCard (TRON / TRC20)</h1>
  <div class='box'><strong>SECURITY:</strong> Print and store offline. Keep your passphrase and this card safe.</div>

  <div class='box'>
    <h2>Wallet</h2>
    <div class='grid'>
      <div><strong>Label</strong><br><code>" . safe($label) . "</code></div>
      <div><strong>Coin</strong><br><code>" . safe($coin) . "</code></div>
      <div><strong>Wallet ID</strong><br><code>" . safe($walletId) . "</code></div>
      <div><strong>Receive Address</strong><br><code>" . safe($receiveAddr) . "</code></div>
    </div>
  </div>

  <div class='box'>
    <h2>User Keychain (You)</h2>
    <div class='grid'>
      <div><strong>xpub</strong><br><code>" . safe($userXpub) . "</code></div>
      <div><strong>encryptedXprv</strong><br><code>" . safe($userEncPrv) . "</code></div>
    </div>
    <p class='muted'>Your private key is <em>encrypted</em> with your passphrase.</p>
  </div>

  <div class='box'>
    <h2>Backup Keychain</h2>
    <div class='grid'>
      <div><strong>xpub</strong><br><code>" . safe($backupXpub) . "</code></div>
      <div><strong>provider</strong><br><code>" . safe($backupProv) . "</code></div>
    </div>
  </div>

  <div class='box'>
    <h2>BitGo Keychain (Co-signer)</h2>
    <div><strong>xpub</strong><br><code>" . safe($bitgoXpub) . "</code></div>
  </div>

  <p class='no-print muted'>Generated: " . safe((new DateTime('now'))->format('c')) . " • File: <code>" . safe($keycardFileName) . "</code></p>
</body>
</html>";

file_put_contents($keycardPath, $html);
chmod($keycardPath, 0600);

// ---- 4) Print EXACT summary lines ----
$signatureProtocol = 'Multisignature';
$perm = 'Admin';
if (is_array($permissions) && count($permissions)) {
  $pl = array_map('strtolower', $permissions);
  if (in_array('admin', $pl, true)) { $perm = 'Admin'; }
  elseif (in_array('spend', $pl, true)) { $perm = 'Spend'; }
  elseif (in_array('view',  $pl, true)) { $perm = 'View'; }
  else { $perm = ucfirst($permissions[0]); }
}
$dateLabel = $created->format('M j, Y, g:i:s A') . ' ' . gmt_offset_label($created);

echo "Label: {$label}\n";
echo "Wallet ID: {$walletId}\n";
echo "Wallet Add: {$receiveAddr}\n";
echo "Signature Protocol: {$signatureProtocol}\n";
echo "Your Permissions: {$perm}\n";
echo "Creation Date: {$dateLabel}\n\n";
echo "KeyCard saved to: {$keycardPath}\n";

Выполнить команду


Для локальной разработки. Не используйте в интернете!