0

我正嘗試在他們的本機API上對Blackberry使用RSA加密。我在Java中創建了公鑰/私鑰對,並將密鑰的模數和指數保存爲字符串,這樣我就可以從中生成用於加密和解密的密鑰。下面的代碼是從客戶端,我得到一個InvalidKeyException和回溯是空,因此我不知道發生了什麼事:在BlackBerry上使用RSA加密時出錯

public byte[] Encrypt(byte[] data) 
    { 
     try { 
      RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024); 
      RSAPublicKey publicKey = new RSAPublicKey(cryptoSystem, _publicKeyExponent.getBytes(), _publicKeyModulus.getBytes()); 
      RSAEncryptorEngine encryptorEngine = new RSAEncryptorEngine(publicKey); 

      PKCS5FormatterEngine formatterEngine = new PKCS5FormatterEngine(encryptorEngine); 

      ByteArrayOutputStream output = new ByteArrayOutputStream(); 
      BlockEncryptor encryptor = new BlockEncryptor(formatterEngine, output); 

      encryptor.write(data); 
      encryptor.close(); 
      output.close(); 

      return output.toByteArray(); 
     } catch (InvalidKeyException e) { 
      // TODO Auto-generated catch block 
      System.out.println(); 
      e.printStackTrace(); 
     } catch (CryptoTokenException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (CryptoUnsupportedOperationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (UnsupportedCryptoSystemException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return null; 
    } 

這是我做的服務器端生成我的鑰匙:

try { 
      keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
      keyPairGenerator.initialize(1024); 
      keyFactory = KeyFactory.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     keyPair = keyPairGenerator.generateKeyPair(); 
     publicKey = keyPair.getPublic(); 
     privateKey = keyPair.getPrivate(); 

     try { 
      publicKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class); 
      privateKeySpec = keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class); 
     } catch (InvalidKeySpecException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     privateKeyModulus = privateKeySpec.getModulus().toString(); 
     privateKeyExponent = privateKeySpec.getPrivateExponent().toString(); 

     publicKeyModulus = publicKeySpec.getModulus().toString(); 
     publicKeyExponent = publicKeySpec.getPublicExponent().toString(); 

任何想法?

編輯:我試圖通過加密和解密那裏的時候做服務器上一個簡單的測試,當我嘗試解密,我得到一個IllegalBlockSizeException這些都是我encrytion和解密方法(服務器端):

public byte[] Decrypt(byte[] data) 
    { 
     try { 
      Cipher cipher = Cipher.getInstance("RSA"); 
      cipher.init(Cipher.DECRYPT_MODE, privateKey); 
      byte[] cipherData = cipher.doFinal(data); 
      return cipherData; 
     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (NoSuchPaddingException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(IllegalBlockSizeException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(InvalidKeyException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(BadPaddingException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     return null; 
    } 

    public byte[] Encrypt(byte[] data) 
    { 
     try { 
      Cipher cipher = Cipher.getInstance("RSA"); 
      cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
      byte[] cipherData = cipher.doFinal(data); 
      return cipherData; 
     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (NoSuchPaddingException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(IllegalBlockSizeException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(InvalidKeyException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } catch(BadPaddingException ex) { 
      Logger.getLogger(EncryptorDecryptor.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     return null; 
    } 

這是一個簡單的測試,我試着:

userName = Base64.encode(encryptorDecryptor.Encrypt(userName.getBytes())); 
password = Base64.encode(encryptorDecryptor.Encrypt(password.getBytes())); 

userName = new String(encryptorDecryptor.Decrypt(Base64.decode(userName))); 
password = new String(encryptorDecryptor.Decrypt(Base64.decode(password))); 

回答

1
  1. 它是使用String作爲任意隨機字節,如一個容器中的錯誤userName = new String(encryptorDecryptor.Encrypt(userName.getBytes())); 是錯誤的。
  2. 我不熟悉Blackberry的Java API,但通常不能使用RSA加密多個塊
  3. 數組上的toString()方法(例如publicKeySpec.getModulus().toString())不會返回任何有用的東西。您應該能夠通過查看數據來了解這一點。這實際上是一個初學java的錯誤,而不僅僅是一個密碼問題。
  4. 不要使用String構造函數和String.getBytes()方法的默認字符集。總是指定一個字符集,通常「UTF-8」是完美的。

這就是我所有的耐心。

+0

我知道把它們保存爲字符串不是最好的做法,但它只是一個服務器端隔離測試,其思想是我收到一個Base64編碼的字節數組並將其轉換爲它所表示的正確字符串(如新編輯)。在服務器上的Java代碼中,我沒有問題使用這種方式的模數和指數來生成密鑰,因此可以進行加密和解密,正如您在最終代碼片段中所看到的(我對其進行了編輯)。如果我錯了,那麼正確的方式怎麼樣? – 8vius 2011-03-10 13:29:37

+0

另外.getModulus()方法返回一個BigInteger而不是一個byte [] – 8vius 2011-03-10 14:13:22