По всем источникам, которые я могу найти, «домены» лука / скрытого сервиса генерируются этот процесс:
Generate a 1024-bit RSA keypair
Take the SHA-1 of the public key
Base32 encode the first 80 bytes of the hash
Я попытался повторить это, сначала создание незабываемого тщеславия URL с луком, «zzzzzzycizaamf47.onion». Затем я написал PHP-скрипт для извлечения открытого ключа из этого закрытого ключа, удаления форматирования, хеширования его, усечения до 10 символов и кодирования base32. Прежде всего я обнаружил три разные функции «кодировать как base32», которые дают разные результаты. Это код с результатами, прокомментированными после трех функций:
$privKey = 'MIIEpAIBAAKC ~snip~ azScNv5A';
$rsa = new Crypt_RSA();
$rsa->loadKey($privKey);
$pubKey = $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$pubKey = str_replace(array("\r", "\n", ' ', '=', '-----BEGINRSAPUBLICKEY-----',
'-----ENDRSAPUBLICKEY-----'), '', $pubKey); //
$pubKey = sha1($pubKey);
$pubKey = substr($pubKey, 0, 10);echo base_convert($pubKey, 16, 32).PHP_EOL; //Result: 68s3ii2
echo crockford32_encode($pubKey).PHP_EOL; //Result: 60rkjcb365hp2d1j
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
echo $base32->encode($pubKey).PHP_EOL; //Result: GAYTSMLDGFRWCNBS
Что здесь не так? Почему три функции «base32» дают разные результаты? Вот код для crockford32_encode, а также вот код для Base2n. Я попробовал почти все комбинации форматирования / удаления пробелов и усечения символов, и никогда не подходил близко к желаемому «zzzzzzycizaamf47».
Спасибо @Yawning Angel, ваш ответ помог, также ответ в этот вопрос, код:
function privkey2pubkey($privKey) {
$privKey = str_replace(array("\r", "\n", ' ', '=', '-----BEGINRSAPRIVATEKEY-----',
'-----ENDRSAPRIVATEKEY-----'), '', $privKey);
$rsa = new Crypt_RSA(); $rsa->loadKey($privKey);
return $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
}
function pubkey2addr($pubKey) {
$pubKey = str_replace(array("\r", "\n", ' ', '=', '-----BEGINRSAPUBLICKEY-----',
'-----ENDRSAPUBLICKEY-----'), '', $pubKey);
$pubKey = base64_decode($pubKey);
$pubKey = sha1($pubKey, true);
$pubKey = substr($pubKey, 0, 10);
$base32 = new Base2n(5, 'abvdefghijklmnopqrstuvwxyz234567', FALSE, TRUE, TRUE);
$pubKey = $base32->encode($pubKey).PHP_EOL;
return $pubKey;
}
Требуется phpseclib и Base2n
Других решений пока нет …