2017-03-09 57 views
2

我有這樣的代碼將數據與RSA加密:JavaCard的RSA密碼DoFinal異常

private static RSAPrivateKey smartcard_rsa_private = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, false); 
private static RSAPublicKey smartcard_rsa_public = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_512, false); 
private static Cipher cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false); 

KeyPair kp = new KeyPair(smartcard_rsa_public,smartcard_rsa_private); 
kp.genKeyPair(); 
smartcard_rsa_private=(RSAPrivateKey)kp.getPrivate(); 
smartcard_rsa_public=(RSAPublicKey)kp.getPublic(); 
byte[] buffer = apdu.getBuffer(); 
cipher.init(smartcard_rsa_public, Cipher.MODE_ENCRYPT); 
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short) apdu.setIncomingAndReceive(), buffer, (short)0); 

我發送以下APDU:

byte[] data = new byte [64]; 
new CommandAPDU(0x80, 0x01, 0x00, 0xff, data); 

我得到一個錯誤代碼5,而doFinal這應該是以下之一:

CryptoException.ILLEGAL_USE如果符合以下條件之一:

  • 此密碼算法不填充消息,消息不是 塊對齊。
  • 此密碼算法不填充消息,也沒有 輸入數據已經在inBuff或通過update()方法提供。
  • 輸入消息長度不被支持或消息值爲 大於或等於模數。
  • 解密的數據不受合適的填充字節限制。
+0

你能告訴我們你發送的APDU嗎?它看起來像填充問題。 – vojta

+0

@vojta我更新了問題 – Florian

回答

2

您的明文不是塊對齊的,因爲你的輸入數據的長度爲64,但與公鑰的512位單RSA明文塊的長度爲53字節。

對於一個n位RSA密鑰,直接加密適用於高達n/8 - 11字節的任意二進制消息(假設n可以被8整除,通常當然是)。

真正的問題是爲什麼使用RSA進行加密而沒有任何填充機制。沒有理由,真的。改爲使用ALG_RSA_PKCS1

如果您需要對長數據進行加密,請使用AES進行加密,並將與RSA一起加密的AES密鑰與消息一起共享。不對稱密碼非常慢。

+0

速度太慢可能是最不重要的原因,爲什麼你只想使用RSA加密**對稱密碼的隨機**鍵而不是加密實際數據... –

+0

@MichaelRoland提高我的答案請,如果你有任何想法。我認爲速度是最重要的原因......你知道甚麼其他原因? – vojta

+1

參見例如http://crypto.stackexchange.com/a/126/25798(TL;密文大小的DR開銷和獲得塊鏈接的權利) –