我產生Python中的密鑰對使用pycrypto用Python驗證的密鑰簽名,不會用Java?
key=RSA.generate(bit_size,os.urandom)
exportedPrivateKey = key.exportKey('PEM', None, pkcs=1).decode("utf-8")
exportedPublicKey = key.publickey().exportKey('PEM', None, pkcs=1).decode("utf-8")
我寫了一個小程序,需要一個消息和體徵哈希散列...
hash = MD5.new(json_info.encode("utf-8")).digest()
privateKey = RSA.importKey(USER_TOKEN_PRIVATE_KEY)
signature = privateKey.sign(hash,'')
然後我寫的東西,所使用的公鑰來驗證它驗證okay..the簽名在我的令牌做工精細..
hash = MD5.new(packet.encode("utf-8")).digest()
publicKey = RSA.importKey(tokenPublicKey)
if publicKey.verify(hash, signature):
return json.loads(packet)
else:
return None
現在,因爲我需要在Java中使用此作爲WEL l作爲python,我正在向java移植一個類似的庫,但我開始遇到問題。也就是說,我的驗證總是失敗......
我通過創建從我導出PEM的公鑰對象開始......
byte[] encoded = Base64.decodeBase64(USER_TOKEN_PUBLIC_KEY);
//decode the encoded RSA public key
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pubKey = kf.generatePublic(keySpec);
我能得到簽名,這是完全一樣的簽名和值散列到完全相同的值(好吧,類似; java代表字節作爲有符號整數,而python代表它們是無符號的,但它們是相同的二進制表示)。但它似乎總是無法驗證我的signature..here是我用來做什麼:
byte[] hash = hasher.digest(packet.getBytes("UTF-8"));
InputStream hashStream = new ByteArrayInputStream(hash);
final Signature sign = Signature.getInstance("MD5withRSA");
sign.initVerify(pubKey);
byte[] buffer = new byte[256];
int length;
while ((length = hashStream.read (buffer)) != -1)
sign.update (buffer, 0, length);
hashStream.close();
System.out.println(sign.verify(signature.getBytes("UTF-8")));
不幸的是,這只是打印錯誤。
我可以真正看到的唯一區別是,當我通過它來驗證在Java中,它要求一個long數組,而在python中它需要一個字節序列。我最好的猜測是採取這個長的字符串表示,並將其轉換成一堆字節,但失敗了。我所有的其他嘗試都失敗了(查看底層大整數的字節表示,查看數組的字節表示等)。我覺得我錯過了一些非常簡單的事情,但對於我的生活,我無法弄清楚它是什麼...
對於簽名看起來像在python中的例子,我給了:
[688304594898632574115230115201042030356261470845487427579402264460794863484312 120410963342371307037749493750151877472804877900061168981924606440672704577286260 395240971170923041153667805814235978868869872792318501209376911650132169706471509 89646220735762034864029622135210042186666476516651349805320771941650]
那麼我該如何對待簽名?它傳遞給我作爲一個消息,所以我把它作爲一個字符串,但我可以適當地投它。我遇到的問題是,它的任何合理的轉換也失敗了,我只是不知道該怎麼做。 – DivineWolfwood
告訴我們簽名的樣子,如果我不知道編碼簽名字符串。如果它只是作爲一種編碼傳遞而沒有不可打印的字符,那麼您正在丟失傳輸中的數據,而且您幾乎無法做到。 –
在python中,它基本上是作爲一個大整數的數組傳遞的,並且它適當地進行了驗證。這裏有一個例子:「[68830459489863257411523011520104203035626147084548742757940226446079486348431212041096334237130703774949375015187747280487790006116898192460644067270457728626039524097117092304115366780581423597886886987279231850120937691165013216970647150989646220735762034864029622135210042186666476516651349805320771941650]」 – DivineWolfwood