【问题标题】:Error while using RSA encryption on BlackBerry在 BlackBerry 上使用 RSA 加密时出错
【发布时间】:2011-03-09 16:10:48
【问题描述】:

我正在尝试在 Blackberry 上通过其原生 API 使用 RSA 加密。我在 Java 中制作了一个公钥/私钥对,并将密钥的模数和指数保存为字符串,这样我就可以从中生成密钥以进行加密和解密。以下代码来自客户端,我得到一个InvalidKeyException 并且回溯为空,所以我不知道发生了什么:

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 这些是我的加密和解密方法(服务器端):

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)));

【问题讨论】:

    标签: blackberry java-me rsa encryption-asymmetric public-key-encryption


    【解决方案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”是完美的。

    这就是我的耐心。

    【讨论】:

    • 我知道将它们保存为字符串不是最佳实践,但它只是服务器端隔离测试,我的想法是我收到一个 Base64 编码的字节数组并将其转换为它代表的正确字符串(如新编辑中所示)。在服务器上的 Java 代码中,我以这种方式使用模数和指数生成密钥并因此进行加密和解密没有问题,正如您在最终代码 sn-p 中看到的那样(我对其进行了编辑)。如果我错了,那么正确的方式是什么?
    • 同样 .getModulus() 方法返回 BigInteger 而不是 byte[]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 2015-08-11
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 2015-04-02
    • 2019-05-08
    相关资源
    最近更新 更多