2013-10-08 5 views
5

के साथ adbkey.pub लोड करने के लिए, Google ने एडीबी पर आरएसए प्रमाणीकरण लागू किया। मेरे पास यूएसबी ओटीजी के साथ कॉर्टेक्स-एम 0 बोर्ड है, जो एडीबी पर एंड्रॉइड के साथ संचार करता है। अब मुझे फर्मवेयर में आरएसए प्रमाणीकरण तैनात करना है।एंड्रॉइड v4.2.2 के बाद से Python आरएसए

मैंने एंड्रॉइड एडीबी, एवीआरक्रिप्टोलिब/एआरएमसीप्रिप्टोलिब से स्रोत कोड एकत्र किए हैं। चूंकि मैं आरएसए प्रमाणीकरण की नौसिखिया हूं, इसलिए मैं अपनी दुबली शुरुआत के रूप में पाइथन आरएसए मॉड्यूल का उपयोग करता हूं।

अजगर आरएसए

अजगर आरएसए 2048bit आरएसए कुंजी युग्म उत्पन्न कर सकते हैं, और एन्क्रिप्ट/डिक्रिप्ट, हस्ताक्षर/जनरेट की गई कुंजी जोड़ी के साथ सही ढंग से पुष्टि करें।

-*- coding: utf-8 -*- 
# with_statement is used in Python 2.6+, 
from __future__ import with_statement 
import rsa 
from datetime import datetime 

# load pub/private keys 
with open('adbkey.pub.pem') as publickfile: 
    p = publickfile.read() 
    pubkey = rsa.PublicKey.load_pkcs1(p) 

with open('adbkey.pem') as privatefile: 
    p = privatefile.read() 
    privkey = rsa.PrivateKey.load_pkcs1(p) 

message = 'http://ennovation.sinaapp.com/' 

begin = datetime.now() 
# Encrypt message with pubkey, decrypt it with private key 
crypto = rsa.encrypt(message, pubkey) 
stop1 = datetime.now() 
message = rsa.decrypt(crypto, privkey) 
stop2 = datetime.now() 
print message 
print "EncryptTime = %s, DecryptTime = %s"%(stop1-begin,stop2-stop1) 

begin = datetime.now() 
# Sign message with private key, verify it with public key 
signature = rsa.sign(message, privkey, 'SHA-1') 
stop1 = datetime.now() 
#result = rsa.verify('hello', signature, pubkey) 
result = rsa.verify(message, signature, pubkey) 
stop2 = datetime.now() 

print result 
print "SignTime = %s, VerifyTime = %s"%(stop1-begin,stop2-stop1) 

एंड्रॉयड आरएसए कुंजी

एंड्रॉयड कुंजी युग्म अलग fortmat उपयोग करता है: यहाँ मेरी स्रोत कोड है। Adbkey फ़ाइल में निजी कुंजी मानक पीईएम प्रारूप का उपयोग करती है, जबकि adbkey.pub में सार्वजनिक कुंजी हेडर और फ़ूटर लाइनों के बिना बेस 64 एन्कोडेड प्रारूप का उपयोग करती है।

मूल adbkey.public:

QAAAAOlEXtSnLMF3igx8NMi7u8+LeD7BoVC+v2bvBJnvVsaJ31QtwEzbicob8mlLxEhbGSKdaoXIwwAsWR+7FzlSUW57G9vuqpJDGJ7iEG4+5uYs7KarhiRF3K+hUX6PDIF7gEo/0TgglxvNXmTkfV9zZb3VxmgV66z68VeBXK46kM7MffKiHyu7P3Jdtdptm2p7jU7XwvfgWH6a0rrrGzUWONEfteh6ruHIxP1Z3CdxYVZ0YF9uHWsweQzgf7N2RG0g4cxNJDLs0CXqaao7xS16tzaCYfn7cZQPIKCb057oo+jMWvgsh+8gY8qgQtI5EHBizd7cPp3S/rVbzN8gUCo4aSuIn9TfT6uJ0S3D3TPWbHXs9Y8nskhIOM1Hkgv3CAODfzwH+ZM3nWmFD77FMtiWo/hJrMRcH63yvX5pVPYnqQyHcdembEM1Fbxg/qWAVtLxNFJqoFKYXYHl9ktGcM+3Izwvea5fAebmbWIuezKYF6F49Y3dIPA+fWxunGkbehih7o0S9RoWIQIYByteF+b/EN2ntSpwfuhD8G9n6Bfaz4mEVTG82Lj8YeK6+CYyEirSCl4Al7SGsb66E74Fnt+v+NouQFpZxCrrefm7sYug11NHSNiDeYa8cnatQsla+Cfd91GmgKsu+ZDO8uF8UR7/r3MKEDohfMCrWdIiZ0w6Ad6hata1OgEAAQA= [email protected]

इसके अलावा, मैंने पाया अजगर आरएसए और एशियाई विकास बैंक से 2048bit आरएसए publice मुख्य अंतर यह लंबाई की है। मैं मैन्युअल रूप से PEM प्रारूप में adbkey.public पुन: फ़ॉर्मेट निम्नलिखित की तरह: कुंजी पीढ़ी के दौरान

Traceback (most recent call last): 
File "D:\Freescale FRDM KL25Z\RSA\rsa_speed_adb.py", line 10, in <module> 
pubkey = rsa.PublicKey.load_pkcs1(p) 
File "build\bdist.win32\egg\rsa\key.py", line 65, in load_pkcs1 
File "build\bdist.win32\egg\rsa\key.py", line 192, in _load_pkcs1_pem 
File "build\bdist.win32\egg\rsa\key.py", line 160, in _load_pkcs1_der 
File "C:\Python25\lib\site-packages\pyasn1-0.1.7-py2.5.egg\pyasn1\codec\ber\decoder.py", line 798, in __call__ pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=64, tagFormat=0, tagId=0)) not in asn1Spec: AsnPubKey() 

मुझे लगता है कि एंड्रॉयड आरएसए कुंजी युग्म (गद्दी) की तरह विभिन्न मापदंडों का उपयोग हो सकता है:

----BEGIN RSA PUBLIC KEY----- 
QAAAAOlEXtSnLMF3igx8NMi7u8+LeD7BoVC+v2bvBJnvVsaJ31QtwEzbicob8mlL 
xEhbGSKdaoXIwwAsWR+7FzlSUW57G9vuqpJDGJ7iEG4+5uYs7KarhiRF3K+hUX6P 
DIF7gEo/0TgglxvNXmTkfV9zZb3VxmgV66z68VeBXK46kM7MffKiHyu7P3Jdtdpt 
m2p7jU7XwvfgWH6a0rrrGzUWONEfteh6ruHIxP1Z3CdxYVZ0YF9uHWsweQzgf7N2 
RG0g4cxNJDLs0CXqaao7xS16tzaCYfn7cZQPIKCb057oo+jMWvgsh+8gY8qgQtI5 
EHBizd7cPp3S/rVbzN8gUCo4aSuIn9TfT6uJ0S3D3TPWbHXs9Y8nskhIOM1Hkgv3 
CAODfzwH+ZM3nWmFD77FMtiWo/hJrMRcH63yvX5pVPYnqQyHcdembEM1Fbxg/qWA 
VtLxNFJqoFKYXYHl9ktGcM+3Izwvea5fAebmbWIuezKYF6F49Y3dIPA+fWxunGkb 
ehih7o0S9RoWIQIYByteF+b/EN2ntSpwfuhD8G9n6Bfaz4mEVTG82Lj8YeK6+CYy 
EirSCl4Al7SGsb66E74Fnt+v+NouQFpZxCrrefm7sYug11NHSNiDeYa8cnatQsla 
+Cfd91GmgKsu+ZDO8uF8UR7/r3MKEDohfMCrWdIiZ0w6Ad6hata1OgEAAQA= 
-----END RSA PUBLIC KEY----- 

तो यह एक त्रुटि फेंकता । हालांकि मुझे नहीं पता कि यह क्या है और इसे कैसे जांचें।

कोई भी विचार मेरी मदद कर सकता है?


अद्यतन

अब मैं लोड और adbkey.pub डिकोड करने के लिए एक रास्ता मिल गया। निम्नलिखित कोड

import base64 
import binascii 

f = open('adbkey.pub','r') # load file from adbkey.pub 
line = f.readline() # actually oneline is enough 
line = line.replace(" [email protected]","") # remove text information 
print line 
print len(line) 
b = base64.b64decode(line) # decode base64 into binary 
s = binascii.hexlify(b) # get hexdecimal of the binary 
print s 

अब मेरे पास पब्की की एक हेक्सडेसीमल प्रस्तुति है।

40000000e9445ed4a72cc1778a0c7c34c8bbbbcf8b783ec1a150bebf66ef0499ef56c689df542dc0 
4cdb89ca1bf2694bc4485b19229d6a85c8c3002c591fbb173952516e7b1bdbeeaa9243189ee2106e 
3ee6e62ceca6ab862445dcafa1517e8f0c817b804a3fd13820971bcd5e64e47d5f7365bdd5c66815 
ebacfaf157815cae3a90cecc7df2a21f2bbb3f725db5da6d9b6a7b8d4ed7c2f7e0587e9ad2baeb1b 
351638d11fb5e87aaee1c8c4fd59dc2771615674605f6e1d6b30790ce07fb376446d20e1cc4d2432 
ecd025ea69aa3bc52d7ab7368261f9fb71940f20a09bd39ee8a3e8cc5af82c87ef2063caa042d239 
107062cddedc3e9dd2feb55bccdf20502a38692b889fd4df4fab89d12dc3dd33d66c75ecf58f27b2 
484838cd47920bf70803837f3c07f993379d69850fbec532d896a3f849acc45c1fadf2bd7e6954f6 
27a90c8771d7a66c433515bc60fea58056d2f134526aa052985d81e5f64b4670cfb7233c2f79ae5f 
01e6e66d622e7b329817a178f58ddd20f03e7d6c6e9c691b7a18a1ee8d12f51a16210218072b5e17 
e6ff10dda7b52a707ee843f06f67e817dacf89845531bcd8b8fc61e2baf82632122ad20a5e0097b4 
86b1beba13be059edfaff8da2e405a59c42aeb79f9bbb18ba0d7534748d8837986bc7276ad42c95a 
f827ddf751a680ab2ef990cef2e17c511effaf730a103a217cc0ab59d222674c3a01dea16ad6b53a 
01000100 

अद्यतन 02

एंड्रॉयड प्रणाली मंच के स्रोत कोड के माध्यम से ब्रीफिंग के बाद, मैं एक टिप्पणी को OpenSSL साथ RSA सार्वजनिक कुंजी संघर्ष, लेकिन microcrypt में समाधान मिल गया।

हालांकि मैं अभी भी सी/सी ++ कार्यान्वयन में जाने से पहले इसे पायथन में लोड करने के लिए काम कर रहा हूं।

उत्तर

3

आपके पास पहले से ही सभी सार्वजनिक कुंजी डीकोडेड हैं; आपको बस सही टुकड़े निकालने की जरूरत है।

एओएसपी परियोजना में एडीबी सार्वजनिक कुंजी के लिए प्रासंगिक शीर्षलेख फ़ाइल mincrypt/rsa.h है।

यह पांच क्षेत्रों के साथ एक संरचना को परिभाषित करता है, इस तरह:

Field  Size 
================================ 
len  4 bytes (1 word) 
n0inv  4 btyes (1 word) 
n  256 bytes (64 words) 
rr  256 bytes (64 words) 
exponent 4 bytes (1 word) 

पूरी संरचना, सभी 524 बाइट्स, base64 एनकोडेड है, और फिर अपने उपयोगकर्ता और होस्ट नाम ([email protected] प्रारूप) के साथ पीछा किया निर्माण करने के लिए adbkey.pub फ़ाइल।

अपने पहले अपडेट के साथ, आप adbkey.pub की सामग्री पढ़ सकते हैं। अब जब कि तुम b है, तो आप दो घटक है कि आप सार्वजनिक कुंजी के लिए की जरूरत निकाल सकते हैं, इस तरह:

n_bytes = bytearray(reversed(b[8:256+8])) # reversed because LSB is first 
n_str = binascii.hexlify(n_bytes)   # convert to hex string 
n = int(n_str, 16)      # make an integer 

e_bytes = bytearray(reversed(b[-4:]))  # last four bytes are the exponent 
e_str = binascii.hexlify(n_bytes) 
e = int(e_str, 16) 

तब उन हिस्सों से एक सार्वजनिक कुंजी बनाने:

pubkey = rsa.PublicKey(n, e) 
+0

मैं यहाँ जोड़ सकते हैं कि एंड्रॉयड RSA कुंजी करने के लिए एक मानक RSA कुंजी के बीच रूपांतरण समारोह 'में कार्यान्वित किया जाता https में पाया RSA_to_RSAPublicKey' : //github.com/android/platform_system_core/blob/master/adb/adb_auth_host.cpp –

0

यहाँ एक पूरा हो गया है जावा में परीक्षण कोड स्निपेट। मैं जानता हूँ कि यह अजगर नहीं है, लेकिन यह यह कन्वर्ट करने के लिए सरल हो सकता है:

/** 
* Parses an Android public RSA key like stored under .android/adbkey.pub and returns a Java public RSA key. 
* @param inputKey The Android public key. 
* @return the public RSA key. 
* @throws Exception 
*/ 
public static PublicKey parseAndroidPubKey(String inputKey) { 
    BufferedReader bufferedReader = new BufferedReader(new StringReader(inputKey)); 
    String line = null; 
    try { 
     line = bufferedReader.readLine(); 
    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
    line = line.replaceAll(" .*@.*", ""); 
    byte[] raw = Base64.getDecoder().decode(line); 
    ByteBuffer bb = ByteBuffer.wrap(raw); 
    bb.order(ByteOrder.LITTLE_ENDIAN); 
    IntBuffer intBuffer = bb.asIntBuffer(); 
    int len = intBuffer.get(); 
    BigInteger n0Inv = BigInteger.valueOf(intBuffer.get()); 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(len*4); 
    int[] dst = new int[len]; 
    intBuffer.get(dst); 
    ArrayUtils.reverse(dst); 
    for (int i = 0; i < len; i++) { 
     int value = dst[i]; 
     byte[] convertedBytes = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(value).array(); 
     byteArrayOutputStream.write(convertedBytes, 0, convertedBytes.length); 
    } 
    byte[] n = byteArrayOutputStream.toByteArray(); 
    byteArrayOutputStream.reset(); 
    dst = new int[len]; 
    intBuffer.get(dst); 
    ArrayUtils.reverse(dst); 
    for (int i = 0; i < len; i++) { 
     int value = dst[i]; 
     byte[] convertedBytes = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(value).array(); 
     byteArrayOutputStream.write(convertedBytes, 0, convertedBytes.length); 
    } 
    int e = intBuffer.get(); 

    RSAPublicKey publicKey; 
    try { 
     publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger(1, n), BigInteger.valueOf(e))); 
    } catch (Exception ex) { 
     throw new RuntimeException(ex); 
    } 
    return publicKey; 
}