2011-04-02 14 views
7

में कनवर्ट करना मैं PHP के ओपनएसएल एक्सटेंशन का उपयोग करके आरएसए कीपैयर उत्पन्न करने के लिए थोड़ी देर के लिए प्रयास कर रहा हूं और परिणाम को ओपनएसएसएच संगत कीपैयर के रूप में सहेज रहा हूं - जिसका मतलब है कि निजी कुंजी पीईएम एन्कोडेड है (जो आसान है) और सार्वजनिक कुंजी निम्न रूप में OpenSSH विशिष्ट प्रारूप में संग्रहीत किया जाता है:ओपनएसएसएच जेनरेटेड आरएसए सार्वजनिक कुंजी को ओपनएसएसएच प्रारूप (पीएचपी)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA...more base64 encoded stuff... 

जहां तक ​​मेरा इकट्ठा कर सकता है इस प्रारूप के होते हैं: स्पष्ट में

  • कुंजी प्रकार पाठ, अंतरिक्ष के बाद (यानी "openssh-rsa")
  • ,210
  • एक बेस 64 इनकोडिंग स्ट्रिंग निम्न डेटा का प्रतिनिधित्व: 32 बिट अहस्ताक्षरित लंबे बड़ा endian
  • एल्गोरिथ्म नाम, इस मामले 'में के रूप में एन्कोड (इस मामले में 7)
    • बाइट में एल्गोरिथ्म नाम की लंबाई SSH- आरएसए ई '
    • आरएसए की लंबाई' 'बाइट में संख्या, 32 बिट अहस्ताक्षरित लंबे बड़ा endian
    • आरएसए के रूप में एन्कोड' ई 'नंबर
    • आरएसए की लंबाई' बाइट में एन 'नंबर, एन्कोडेड 32 बिट हस्ताक्षर किए गए लंबे बड़े एंडियन
    • आरएसए 'एन' संख्या

मैं इस का उपयोग कर PHP के पैक() फ़ंक्शन को लागू करने की कोशिश की है, लेकिन कोई फर्क नहीं पड़ता कि मैं क्या करने की कोशिश परिणाम मैं क्या द्वारा उत्पन्न एक ही RSA निजी कुंजी पर ssh-keygen -y -f आदेश का उपयोग कर से प्राप्त करने के लिए बराबर नहीं है openssl।

<?php 

// generate private key 
$privKey = openssl_pkey_new(array(
    'private_key_bits' => 1024, 
    'private_key_type' => OPENSSL_KEYTYPE_RSA 
)); 

// convert public key to OpenSSH format 
$keyInfo = openssl_pkey_get_details($privKey); 
$data = pack("Na*", 7, 'ssh-rsa'); 
$data .= pack("Na*", strlen($keyInfo['rsa']['e']), $keyInfo['rsa']['e']); 
$data .= pack("Na*", strlen($keyInfo['rsa']['n']), $keyInfo['rsa']['n']); 

$pubKey = "ssh-rsa " . base64_encode($data); 

echo "PHP generated RSA public key:\n$pubKey\n\n"; 

// For comparison, generate public key using ssh-keygen 
openssl_pkey_export($privKey, $pem); 
$umask = umask(0066); // this is needed for ssh-keygen to work properly 
file_put_contents('/tmp/ssh-keygen-test', $pem); 
umask($umask); 

exec('ssh-keygen -y -f /tmp/ssh-keygen-test', $out, $ret); 
$otherPubKey = $out[0]; 
echo "ssh-keygen generated RSA public key:\n$otherPubKey\n\n"; 

echo ($pubKey == $otherPubKey ? "yes! they are the same\n" : "FAIL! they are different\n"); 

?> 

मैं यह कैसे कर सकते हैं पर कोई सुझाव दिए गए ssh-keygen पर निर्भर रहे बिना:

यहाँ मेरी कोड का एक सरलीकृत संस्करण है?

उत्तर

9

ठीक है, मैं सिर्फ एक करीब Convert pem key to ssh-rsa format से सी कार्यान्वयन के संदर्भ में देखो (जो मैं पहले किया था लेकिन जाहिरा तौर पर मैं कुछ महत्वपूर्ण सामान याद किया) लेने के द्वारा अपने ही समस्या हल कर दिया है। मुझे 0x80 के साथ एन और ई के पहले अक्षर की आवश्यकता थी और यदि यह संख्या की शुरुआत में एक और नल चरित्र जोड़ता है और आकार क्रमशः 1 तक बढ़ाता है।

मुझे यकीन नहीं है कि यह क्यों किया जाता है (मुझे ऑनलाइन खोज में इसका कोई संदर्भ नहीं मिला) लेकिन यह काम करता है।

मैं सिर्फ अपने कोड इस पर बुनियादी परीक्षण किया है, लेकिन यह अच्छी तरह से काम करने लगता है, और यहाँ:

<?php 

$privKey = openssl_pkey_get_private($rsaKey); 
$pubKey = sshEncodePublicKey($privKey); 

echo "PHP generated RSA public key:\n$pubKey\n\n"; 

function sshEncodePublicKey($privKey) 
{ 
    $keyInfo = openssl_pkey_get_details($privKey); 

    $buffer = pack("N", 7) . "ssh-rsa" . 
       sshEncodeBuffer($keyInfo['rsa']['e']) . 
       sshEncodeBuffer($keyInfo['rsa']['n']); 

    return "ssh-rsa " . base64_encode($buffer); 
} 

function sshEncodeBuffer($buffer) 
{ 
    $len = strlen($buffer); 
    if (ord($buffer[0]) & 0x80) { 
     $len++; 
     $buffer = "\x00" . $buffer; 
    } 

    return pack("Na*", $len, $buffer); 
} 
?> 
+0

ध्यान दें कि 'sshEncodeBuffer' बाइट लंबाई की आवश्यकता है। यदि आपके पास 'mbstring है।' – bishop

+0

@shevron यह RSA कुंजी के लिए पूरी तरह से काम किया, func_overload' स्ट्रिंग कार्यों ओवरलोड,' 'mb_strlen ($ बफर, '8 बिट') के साथ' strlen ($ बफर) की जगह निर्धारित किया है। लेकिन यह DSA कुंजी के लिए काम नहीं करता। मैं DSA सार्वजनिक कुंजी कैसे बदल सकता हूँ? – Harikrishnan

1

बहुत सरल विधि, phpseclib, a pure-PHP RSA implementation का उपयोग कर:

<?php 
include('Crypt/RSA.php'); 

$rsa = new Crypt_RSA(); 
$rsa->loadKey('-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/ 
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB 
-----END PUBLIC KEY-----'); 
$rsa->setPublicKey(); 

$publickey = $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH); 
?> 

आउटपुट:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== phpseclib-generated-key 

स्रोत:

http://phpseclib.sourceforge.net/rsa/examples.html#public,openssh

संबंधित मुद्दे