33import time
44import os
55
6- import Crypto
6+ from Crypto . Cipher import PKCS1_v1_5
77from Crypto .PublicKey import RSA
8+ from Crypto .Hash import SHA
9+ from Crypto .Random import get_random_bytes
810from Crypto import Random
9- import ast
1011import binascii
1112
1213from onlykey import OnlyKey , Message
1718
1819p = key .p
1920q = key .q
20- d = key .d
21+ n = key .n
2122
2223binPrivKey = key .exportKey ('DER' )
2324binPubKey = key .publickey ().exportKey ('DER' )
24- #privKeyObj = RSA.importKey(binPrivKey)
25- #pubKeyObj = RSA.importKey(binPubKey)
26-
27- def bin2hex (binStr ):
28- return binascii .hexlify (binStr )
29-
30- def hex2bin (hexStr ):
31- return binascii .unhexlify (hexStr )
32-
33- hexPrivKey = bin2hex (binPrivKey )
34- hexPubKey = bin2hex (binPubKey )
3525
3626print 'Done'
3727print
38-
3928print 'RSA p value =' , repr (p )
4029print 'RSA q value =' , repr (q )
41- print 'RSA d value =' , repr (d )
42- print 'pubkey=' , repr (hexPubKey )
43- #print 'pubkey hex=', pubkey.to_ascii(encoding='hex')
44- # not displaying correctly
45- print
46-
30+ print 'RSA n value =' , repr (n )
4731print
4832print 'Initialize OnlyKey client...'
4933ok = OnlyKey ()
@@ -61,11 +45,35 @@ def hex2bin(hexStr):
6145print
6246
6347print 'Setting SSH private...'
48+
49+ def pack_long (n ):
50+ """this conert 10045587143827198209824131064458461027107542643158086193488942239589004873324146472911535357118684101051965945865943581473431374244810144984918148150975257L
51+ to "\xbf \xcd \xce \xa0 K\x93 \x85 }\xf0 \x18 \xb3 \xd3 L}\x14 \xdb \xce 0\x00 uE,\x05 '\xee W\x1c \xeb \xcf \x8b \x1f \xcc \xc5 \xc1 \xe2 \x17 \xb7 \xa3 \xb6 C\x16 \xea ?\xcc hz\xeb F1\xb7 \xb1 \x86 \xb8 \n }\x82 \xeb x\xce \x1b \x13 \xdf \xdb \x19 "
52+ it seems to be want you wanted? it's 64 bytes.
53+ """
54+ h = '%x' % n
55+ s = ('0' * (len (h ) % 2 ) + h ).decode ('hex' )
56+ return s
57+
58+ def bin2hex (binStr ):
59+ return binascii .hexlify (binStr )
60+
61+ def hex2bin (hexStr ):
62+ return binascii .unhexlify (hexStr )
63+
64+ hexPrivKey = bin2hex (binPrivKey )
65+ hexPubKey = bin2hex (binPubKey )
66+
6467# p and q are long ints that are no more than 1/2 the size of pubkey
6568# I need to convert these into a single byte array put p in the first
6669# half byte[0] of the byte array and q in the second half byte[(type*128) / 2]
6770# send the byte array to OnlyKey splitting into 56 bytes per packet
68- ok .set_rsa_key (1 , (1 + 64 ), byte array here ) #Can only send 56 bytes per packet
71+ q_and_p = pack_long (q ) + pack_long (p )
72+ public_n = pack_long (n )
73+ #
74+ ok .send_large_message3 (msg = Message .OKSETPRIV , slot_id = 1 , key_type = (1 + 32 ), payload = q_and_p )
75+
76+ # ok.set_rsa_key(1, (1+64), byte array here) #Can only send 56 bytes per packet
6977# Slot 1 - 4 for RSA
7078# Type 1 = 1024, Type 2 = 2048, Type 3 = 3072, Type 4 = 4096
7179# Key Features -
@@ -81,34 +89,53 @@ def hex2bin(hexStr):
8189print 'You should see your OnlyKey blink 3 times'
8290print
8391
84- print 'Trying to read the pubkey ...'
92+ print 'Trying to read the public RSA N part 1 ...'
8593ok .send_message (msg = Message .OKGETPUBKEY , payload = chr (1 )) #, payload=[1, 1])
8694time .sleep (1.5 )
8795for _ in xrange (10 ):
88- ok_pubkey = ok .read_bytes (( 1 * 128 ) , to_str = True )
89- if len (ok_pubkey ) == ( rsatype * 128 ) :
96+ ok_pubkey1 = ok .read_bytes (64 , to_str = True )
97+ if len (ok_pubkey1 ) == 64 :
9098 break
9199 time .sleep (1 )
92100
93101print
94102
95- print 'received=' , repr (ok_pubkey )
103+ print 'received=' , repr (ok_pubkey1 )
96104
97- if not ok_pubkey :
105+ print 'Trying to read the public RSA N part 2...'
106+ for _ in xrange (10 ):
107+ ok_pubkey2 = ok .read_bytes (64 , to_str = True )
108+ if len (ok_pubkey2 ) == 64 :
109+ break
110+ time .sleep (1 )
111+
112+ print
113+
114+ print 'received=' , repr (ok_pubkey2 )
115+
116+ if not ok_pubkey2 :
98117 raise Exception ('failed to set the SSH key' )
99118
100- print 'Assert that the received pubkey match the one generated locally'
101- assert ok_pubkey == pubkey .to_bytes ()
102- print 'Ok, pubkey matches'
119+ print 'Assert that the received public N match the one generated locally'
120+ print 'Local Public N=' , repr (public_n )
121+ ok_pubkey = ok_pubkey1 + ok_pubkey2
122+ assert ok_pubkey == public_n
123+ print 'Ok, public N matches'
103124print
104125
105- test_payload = os .urandom (150 )
106- print 'test_payload=' , repr (test_payload )
126+ message = 'Secret message'
127+ #h = SHA.new(message)
128+ cipher = PKCS1_v1_5 .new (key )
129+ ciphertext = cipher .encrypt (message )
130+
131+ #hex_enc_data = bin2hex(enc_data)
132+ print 'encrypted payload = ' , repr (ciphertext )
107133print
108134
135+
109136# Compute the challenge pin
110137h = hashlib .sha256 ()
111- h .update (test_payload )
138+ h .update (ciphertext )
112139d = h .digest ()
113140
114141assert len (d ) == 32
@@ -122,24 +149,27 @@ def get_button(byte):
122149b1 , b2 , b3 = get_button (d [0 ]), get_button (d [15 ]), get_button (d [31 ])
123150
124151print 'Sending the payload to the OnlyKey...'
125- ok .send_large_message2 (msg = Message .OKSIGNCHALLENGE , payload = test_payload )
152+ ok .send_large_message2 (msg = Message .OKDECRYPT , payload = ciphertext , slot_id = 1 )
126153
127154print 'Please enter the 3 digit challenge code on OnlyKey (and press ENTER if necessary)'
128155print '{} {} {}' .format (b1 , b2 , b3 )
129156raw_input ()
130- time .sleep (0.2 )
131- ok .send_large_message2 (msg = Message .OKSIGNCHALLENGE , payload = test_payload )
132- signature = ''
133- while signature == '' :
157+ print 'Trying to read the decrypted data from OnlyKey...'
158+ ok_decrypted = ''
159+ while ok_decrypted == '' :
134160 time .sleep (0.5 )
135- signature = ok .read_bytes (256 , to_str = True )
161+ ok_decrypted = ok .read_bytes (64 , to_str = True )
162+
163+ dsize = len (message )
164+ sentinel = Random .new ().read (15 + dsize )
165+ plaintext = cipher .decrypt (ciphertext , sentinel )
136166
137- print 'Signed by OnlyKey, signature =' , repr (signature )
167+ print 'Decrypted by OnlyKey, data =' , repr (ok_decrypted )
138168
139- print 'Local signature =' , repr (key . sign ( test_payload , '' ) )
140- print 'Assert that the signature generated locally match the one generated on the OnlyKey'
141- assert repr (signature ) == repr (key . sign ( test_payload , '' ) )
142- print 'Ok, signatures match '
169+ print 'Local decrypted data =' , repr (plaintext )
170+ print 'Assert that the decrypted data generated locally matches the data generated on the OnlyKey'
171+ assert repr (ok_decrypted ) == repr (plaintext )
172+ print 'Ok, data matches '
143173print
144174
145175print 'Done'
0 commit comments