Неизвестные символы при запуске при анализе закрытого ключа в асимметричном алгоритме

Я пытаюсь реализовать асимметричный алгоритм в Android. У меня все получилось. Но я столкнулся с проблемой при выводе.

Что я получаю после расшифровки с помощью закрытого ключа (который содержит фактический текст в конце):

�������\�C���gz�{ܳkK��c��LB(7fz���H�8�� ��ȏ�ҍ�X    ��KI��aj�B��x�D�n>�ι�&
    UL-1���E�;��s9�zB[�9B�t��B�A�s�GA6����y�f���J�����+.
    `g4�s�1��p�PW�%��7�"��fQ����G���x� �|&�ѡ�gq������:X�be�_��av��{'msg':'Laravel 7.7777777'}

Фактическое сообщение:

{'msg':'Laravel 7.7777777'}

Вы можете ясно видеть, что он присутствует в расшифрованной строке. Я знаю, что это из-за какой-то строки или какой-то другой глупой ошибки или чего-то в этом роде. Но я не могу получить это. Даже мои зашифрованные данные также имеют ту же проблему, когда они достигают сервера. Но когда я шифрую и расшифровываю, в конце концов, все работает нормально. Это происходит при замене ключа.

Здесь я прикрепляю свой фактический класс, который отвечает за асимметричное шифрование. С открытым и закрытым ключом. Вместе с зашифрованным текстом необходимо расшифровать.

public class AsymmetricHandler {

    String ALGO_TYPE = "RSA";
    String CIPER_TYPE = "RSA";
//    String CIPER_TYPE = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";

    private static AsymmetricHandler instance = null;

    public static AsymmetricHandler getInstance() {
        if (instance == null) {
            Security.setProperty("crypto.policy", "unlimited");
            instance = new AsymmetricHandler();
        }
        return instance;
    }


    public PublicKey getActualPublicKey(String base64EncryptedStringKey) throws Exception {
        KeyFactory kf = KeyFactory.getInstance(ALGO_TYPE);
        X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.decode(base64EncryptedStringKey.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", ""), Base64.DEFAULT));

        return kf.generatePublic(keySpecX509);
    }

    public PrivateKey getActualPrivateKey(String base64EncryptedStringKey) throws Exception {
        KeyFactory kf = KeyFactory.getInstance(ALGO_TYPE);
        PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(base64EncryptedStringKey.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", ""), Base64.DEFAULT));

        return kf.generatePrivate(keySpecPKCS8);
    }

    public String decodeBase64String(String value) {
        return new String(Base64.decode(value, Base64.DEFAULT));
    }

    public String encodeToBase64String(String value) {
        return new String(Base64.encode(value.getBytes(), Base64.DEFAULT));
    }


    // Get RSA keys. Uses key size of 2048.
    public Map<String, Object> getRSAKeys() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGO_TYPE);
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        Map<String, Object> keys = new HashMap<String, Object>();
        keys.put("private", privateKey);
        keys.put("public", publicKey);
        return keys;
    }


    public String encryptString(String msg, PublicKey key)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            IllegalBlockSizeException,
            BadPaddingException, InvalidKeyException {

//        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
        Cipher cipher = Cipher.getInstance(CIPER_TYPE);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return Base64.encodeToString(cipher.doFinal(msg.getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT);
    }

    public String decryptString(String msg, PrivateKey key)
            throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {

        try {
//            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            Cipher cipher = Cipher.getInstance(CIPER_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, key);
            return new String(cipher.doFinal(Base64.decode(msg, Base64.DEFAULT)), StandardCharsets.UTF_8);


        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            e.printStackTrace();
        }

        return null;
    }

}

Вот пример ключа и значения, которые я использую.

 String stringPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApSNOjR5QWU4H24OAhPHaJwq7/9Nqzcfiiau4o51+yopr9RG2ZDjpoeP/DEL/Frnz+PRrcdwiZxtk00qVqz15Y/eOc3VsOGHYbPYI6Q27n4L/t1PRHw/9AWjWHomxNvSpxkgg3ABFUdfYVoPDYqbm9Vu1m50sHzqEGBX9xIdgYjlWrjsKmQD5ciejE+eYOJnXJPKG9oXZJGmiQRgvlaPYL6oj+jfbv5/+FHVgWRqXRXURLSxa85qPVS673hmi6ApqUCnWWNhuZ66S1SypvHnCFQuqLIDILGwMkRvm+SOXJKrtpRdENuQMfdBZjeILYHAgILYgTcCnmnhii35BMJ6kEQIDAQAB";

String stringPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClI06NHlBZTgfbg4CE8donCrv/02rNx+KJq7ijnX7Kimv1EbZkOOmh4/8MQv8WufP49Gtx3CJnG2TTSpWrPXlj945zdWw4Ydhs9gjpDbufgv+3U9EfD/0BaNYeibE29KnGSCDcAEVR19hWg8Nipub1W7WbnSwfOoQYFf3Eh2BiOVauOwqZAPlyJ6MT55g4mdck8ob2hdkkaaJBGC+Vo9gvqiP6N9u/n/4UdWBZGpdFdREtLFrzmo9VLrveGaLoCmpQKdZY2G5nrpLVLKm8ecIVC6osgMgsbAyRG+b5I5ckqu2lF0Q25Ax90FmN4gtgcCAgtiBNwKeaeGKLfkEwnqQRAgMBAAECggEAewKL1s7H514auEeCioVljUOPuwcPPe4xL3/879O3yMPHmyvwg0NptTASol2dip5FwCLBjnT+I3PibQnX51DJhc+4CwVi8bTg9HlpNcEHC9EXDsaetdbBDjW7mc/TdC5X8N11rKt+93IjMn7AIlJVJFuGMj6nyTNbhl2LRMPa5g67+FlXbAu4YTK5FuR1P8AKAyjECmiw0dov8FNHtmrQhcsAdB4I8EHNzyFnDmA9ecsnSQGw05p82JC11r6UlpI3zvcHwX9XtfzphbEW0rQ3eVzek4p9Nvi0z1wvOuHHqNYGlOGePX3tH0TY7+g41TZZwZEEUnH79ySd/nnorYdwAQKBgQD57s/ICRcZp9eKtdyGvKh2TBM1URt47l4cHNAJU+SoSAokAUZDtaWSvvpQmSSHL2CvkY6nbH95IlgHvQphW2sjGQNhEBnbaZJ9p+JfJ+nvRrKR8kc9ZsR9TpAatKIA/0vl2dnX7ugYUk4Hz2aIAIDfCA74oEz1PoBhzel92ZOTgQKBgQCpJYsqXqVP9DTV5Zd4M69LijVwhub8rYH/LiezFyReqtQ1IUG8triYveRpbu9h/zEPZGGl8xfapH+u4KanI8/glbR+Ef3cz2oFaQ7Hs9TVSI04UYCdZsf1PojTpUCJmWPxHT55855Nxclny9aIuf+vDV/WbiqH3eE3ljMNKDQYkQKBgBIdWvX2orP7VEX7dGZXmiYo0WOV41XagPusou9qIzKHNiTx6rPRoJSIPwBEeT9LEcjn1d0QohSXhqXY772qsJM0pugMELO0bSeqWV/oNq5fA2ZMlxk+L5OddBhbazqDRm78YSujZzMMFBfA0n+c+bowjVU72RgVVZzBHeE/OdEBAoGATQh7K8207gfi9DM+25B2WinUkq3tjtAabzP/ApIcjzyvro652I9C3NVGrDnIrdHB7yehTSm8CGh4ehV38JDfwIGNlQjum9yehV5GS+77lDMZlbeQop7HnEphmDoffUsteAcAiBvKUdMtGad8ygIjjv7BUfAUUJJdWqp+D5TqvPECgYEAtLfIbEy3vwYpLYAKZiTQPwuy18UNV6vOPnyLwJ3d/LQ0slnbfO6gL1nS8gnzEGLtN/MRwYjJsUW5F2gzcnLPPmOTiuGFt0d3TqMTnnPaAtmR2Y1vxfwrdf8xtyJfDgtM59mCPjnJNQIinD4Nn/AMhsUC3AfejkeJfOEyYXvnO/k=";

String encryptedText = "OqY8zdB44msKeJ8ysu6HwO/LcwldWly6rTsd3GSxjZ2U9ncSVGjEVaWNeaYROHMJY3YmJMpFQ0bwDUUnWDjOqjNU15O2gKH6N+l4BD2jiYhcSXSgGFPLvQrS+Fb865/Y9f/U9Jqi7zBZtTEXuktIrcCb8Drr3aaT8q3yHEWPCfBBzxtffm60WHU0k1hM6EtZiXufCjD3q4ILEzs/+IOnoZ8njCIc15DD/YN9fBRIifw+zy+EFpCWLlzDeejR2wwqVyENQSmfiChC4EVnULqfHfeSWOqK/QVATYC6ljkr+G4QQQ82VQ8sRGS6x40ClKINTerqKxhSpwNoNuaDqmBkHw=="

person Ranjan    schedule 16.04.2020    source источник
comment
Ну, RSA/ECB/OAEP с SHA-1 и MGF1Padding не работает для меня. Но у меня сработал RSA/ECB/PKCS1Padding. Спасибо @Robert за то, что указал мне правильное направление.   -  person Ranjan    schedule 16.04.2020


Ответы (1)


Ваша ошибка в том, что вы используете простой RSA без заполнения при расшифровке зашифрованных данных.

При шифровании данных с помощью RSA размер данных должен иметь определенную длину. Если данные, которые нужно зашифровать, слишком короткие, их необходимо увеличить до нужного размера, добавив байты заполнения (что, очевидно, делается кодом, который шифрует данные).

Проблема не в том, что вы расшифровываете данные без дополнения и, следовательно, получаете данные заполнения плюс расшифрованное сообщение.

Поэтому обязательно используйте для шифрования и дешифрования один и тот же алгоритм заполнения. В вашем коде уже указано OAEPWithSHA-1AndMGF1Padding в качестве заполнения, но соответствующие части закомментированы.

Используйте RSA/ECB/OAEPWithSHA-1AndMGF1Padding для шифрования и расшифровки, и данные заполнения будут автоматически удалены при расшифровке.

person Robert    schedule 16.04.2020
comment
Итак, то, что я прокомментировал, является фактической ошибкой (т. Е. CIPER_TYPE). - person Ranjan; 16.04.2020
comment
@Ranjan Похоже, вы загрузили библиотеку BouncyCastle, и с Bouncycastle вам необходимо указать заполнение, иначе используется NoPadding. Поэтому выберите дополнение и используйте его для шифрования и дешифрования. - person Robert; 16.04.2020
comment
Нет, я не использовал библиотеку Bounty Castle. Но я получаю javax.crypto.BadPaddingException при использовании RSA/ECB/OAEPWithSHA-1AndMGF1Paddin - person Ranjan; 16.04.2020
comment
@Ranjan Обязательно используйте RSA/ECB/OAEPwithSHA-1andMGF1Padding для шифрования и дешифрования (восстановите строку encryptionText). И, конечно же, используйте одну и ту же пару ключей — сгенерируйте пару ключей только один раз, а затем сохраните ее. - person Robert; 16.04.2020