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