Skip to content

Commit 8ff0b83

Browse files
onlykeyonlykey
authored andcommitted
RSA decrypt working, signing still needs work
1 parent d82ecf4 commit 8ff0b83

2 files changed

Lines changed: 118 additions & 69 deletions

File tree

tests/rsa_decrypt_1024.py

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import time
44
import os
55

6-
import Crypto
6+
from Crypto.Cipher import PKCS1_v1_5
77
from Crypto.PublicKey import RSA
8+
from Crypto.Hash import SHA
9+
from Crypto.Random import get_random_bytes
810
from Crypto import Random
9-
import ast
1011
import binascii
1112

1213
from onlykey import OnlyKey, Message
@@ -17,33 +18,16 @@
1718

1819
p = key.p
1920
q = key.q
20-
d = key.d
21+
n = key.n
2122

2223
binPrivKey = key.exportKey('DER')
2324
binPubKey = 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

3626
print 'Done'
3727
print
38-
3928
print 'RSA p value =', repr(p)
4029
print '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)
4731
print
4832
print 'Initialize OnlyKey client...'
4933
ok = OnlyKey()
@@ -61,11 +45,35 @@ def hex2bin(hexStr):
6145
print
6246

6347
print 'Setting SSH private...'
48+
49+
def pack_long(n):
50+
"""this conert 10045587143827198209824131064458461027107542643158086193488942239589004873324146472911535357118684101051965945865943581473431374244810144984918148150975257L
51+
to "\xbf\xcd\xce\xa0K\x93\x85}\xf0\x18\xb3\xd3L}\x14\xdb\xce0\x00uE,\x05'\xeeW\x1c\xeb\xcf\x8b\x1f\xcc\xc5\xc1\xe2\x17\xb7\xa3\xb6C\x16\xea?\xcchz\xebF1\xb7\xb1\x86\xb8\n}\x82\xebx\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):
8189
print 'You should see your OnlyKey blink 3 times'
8290
print
8391

84-
print 'Trying to read the pubkey...'
92+
print 'Trying to read the public RSA N part 1...'
8593
ok.send_message(msg=Message.OKGETPUBKEY, payload=chr(1)) #, payload=[1, 1])
8694
time.sleep(1.5)
8795
for _ 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

93101
print
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'
103124
print
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)
107133
print
108134

135+
109136
# Compute the challenge pin
110137
h = hashlib.sha256()
111-
h.update(test_payload)
138+
h.update(ciphertext)
112139
d = h.digest()
113140

114141
assert len(d) == 32
@@ -122,24 +149,27 @@ def get_button(byte):
122149
b1, b2, b3 = get_button(d[0]), get_button(d[15]), get_button(d[31])
123150

124151
print '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

127154
print 'Please enter the 3 digit challenge code on OnlyKey (and press ENTER if necessary)'
128155
print '{} {} {}'.format(b1, b2, b3)
129156
raw_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'
143173
print
144174

145175
print 'Done'

tests/ssh_auth_rsa_1024.py

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import time
44
import os
55

6+
from Crypto.Signature import PKCS1_v1_5
7+
from Crypto.Hash import SHA
68
from Crypto.PublicKey import RSA
79
from Crypto import Random
810
import binascii
@@ -115,19 +117,23 @@ def pack_long(n):
115117
if not ok_pubkey2:
116118
raise Exception('failed to set the SSH key')
117119

118-
print 'Assert that the received pubkey match the one generated locally'
120+
print 'Assert that the received public N match the one generated locally'
121+
print 'Local Public N=', repr(public_n)
119122
ok_pubkey = ok_pubkey1 + ok_pubkey2
120123
assert ok_pubkey == public_n
121-
print 'Ok, pubkey matches'
124+
print 'Ok, public N matches'
122125
print
123126

124-
test_payload = os.urandom(150)
125-
print 'test_payload=', repr(test_payload)
127+
test_payload1 = os.urandom(100)
128+
h = hashlib.sha1()
129+
h.update(test_payload1)
130+
test_payload2 = h.digest()
131+
print 'test_payload=', repr(test_payload2)
126132
print
127133

128134
# Compute the challenge pin
129135
h = hashlib.sha256()
130-
h.update(test_payload)
136+
h.update(test_payload2)
131137
d = h.digest()
132138

133139
assert len(d) == 32
@@ -141,40 +147,53 @@ def get_button(byte):
141147
b1, b2, b3 = get_button(d[0]), get_button(d[15]), get_button(d[31])
142148

143149
print 'Sending the payload to the OnlyKey...'
144-
ok.send_large_message2(msg=Message.OKSIGNCHALLENGE, payload=test_payload, slot_id=1)
150+
ok.send_large_message2(msg=Message.OKSIGNCHALLENGE, payload=test_payload2, slot_id=1)
145151

146152
print 'Please enter the 3 digit challenge code on OnlyKey (and press ENTER if necessary)'
147153
print '{} {} {}'.format(b1, b2, b3)
148154
raw_input()
149155
print 'Trying to read the signature part 1...'
150-
for _ in xrange(10):
156+
signature1 = ''
157+
while signature1 == '':
158+
time.sleep(0.5)
151159
signature1 = ok.read_bytes(64, to_str=True)
152-
if len(signature1) == 64:
153-
break
154-
time.sleep(1)
155-
156-
print
157160

158161
print 'received=', repr(signature1)
159162

160163
print 'Trying to read the signature part 2...'
161-
for _ in xrange(10):
164+
signature2 = ''
165+
while signature2 == '':
166+
time.sleep(0.5)
162167
signature2 = ok.read_bytes(64, to_str=True)
163-
if len(signature2) == 64:
164-
break
165-
time.sleep(1)
166-
167-
print
168168

169169
print 'received=', repr(signature2)
170170

171-
signature = signature1 + signature2
172-
print 'Signed by OnlyKey, signature=', repr(signature)
171+
ok_signature = signature1 + signature2
172+
print 'Signed by OnlyKey, signature=', repr(ok_signature)
173+
def bytes2int(str):
174+
return int(str.encode('hex'), 16)
175+
176+
# I don't think this is right, need to convert signature to right format
177+
# https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html#verify
178+
# https://www.dlitz.net/software/pycrypto/api/current/Crypto.Signature.PKCS1_v1_5-module.html
179+
180+
h = SHA.new(test_payload1)
181+
verifier = PKCS1_v1_5.new(key)
182+
if verifier.verify(h, ok_signature):
183+
print "The OnlyKey signature is authentic."
184+
else:
185+
print "The OnlyKey signature is not authentic."
186+
187+
188+
h = SHA.new(test_payload1)
189+
signer = PKCS1_v1_5.new(key)
190+
signature = signer.sign(h)
191+
192+
verifier = PKCS1_v1_5.new(key)
193+
if verifier.verify(h, signature):
194+
print "The local signature is authentic."
195+
else:
196+
print "The local signature is not authentic."
173197

174-
print 'Local signature=', repr(key.sign(test_payload, ''))
175-
print 'Assert that the signature generated locally match the one generated on the OnlyKey'
176-
assert repr(signature) == repr(key.sign(test_payload, ''))
177-
print 'Ok, signatures match'
178-
print
179198

180199
print 'Done'

0 commit comments

Comments
 (0)