Ошибка при использовании шифрования RSA на BlackBerry

Я пытаюсь использовать шифрование RSA на Blackberry с их собственным API. Я создал пару открытого / закрытого ключей в 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)));

person 8vius    schedule 09.03.2011    source источник


Ответы (1)


  1. Ошибкой является использование String в качестве контейнера для произвольных случайных байтов, например. userName = new String(encryptorDecryptor.Encrypt(userName.getBytes())); неверно.
  2. Я не знаком с Java API Blackberry, но обычно вы не можете зашифровать более одного блока с помощью RSA.
  3. методы toString () для массивов (например, publicKeySpec.getModulus().toString()) не возвращают ничего полезного. Вы сможете понять это, просто взглянув на данные. Это действительно ошибка начинающего java, больше, чем проблема криптографии.
  4. Не используйте набор символов по умолчанию для конструктора String и методов String.getBytes (). Всегда указывайте набор символов, обычно идеально подходит "UTF-8".

Это все, на что у меня хватило терпения.

person President James K. Polk    schedule 10.03.2011
comment
Я знаю, что сохранение их как String - не лучшая практика, но это просто изолированный тест на стороне сервера, идея состоит в том, что я получаю байтовый массив в кодировке Base64 и конвертирую его в правильную строку, которую он представляет (как показано в новом редактировании) . В коде Java на сервере у меня не было проблем с использованием модуля и экспоненты таким образом для генерации ключей и, следовательно, для шифрования и дешифрования, как вы можете видеть в окончательном фрагменте кода (я внес в него изменения). И если я ошибаюсь, то как будет правильным образом? - person 8vius; 10.03.2011
comment
Также метод .getModulus () возвращает BigInteger, а не byte [] - person 8vius; 10.03.2011