Криптография Java RSA: модуль RSA имеет небольшой простой множитель - PullRequest
1 голос
/ 24 сентября 2019

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

Код для генерации ключа

    generator = KeyPairGenerator.getInstance("RSA");
    RSAKeyGenParameterSpec kpgSpec = new RSAKeyGenParameterSpec(2048, BigInteger.valueOf(17489));
    generator.initialize(kpgSpec);

    KeyPair keyPair = generator.generateKeyPair();

    publicKey = (RSAPublicKey) keyPair.getPublic();
    privateKey = (RSAPrivateKey) keyPair.getPrivate();

Код для шифрования сообщений

        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(publicKeyBytes), BigInteger.valueOf(17489));

    Cipher cipher;
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey currentKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
    cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, currentKey);
    byte[] encryptedBytes = cipher.doFinal(data.getBytes());
    encrypted = bytesToString(encryptedBytes);

Ошибка:

W/System.err: java.lang.IllegalArgumentException: RSA modulus has a small prime factor
W/System.err:     at com.android.org.bouncycastle.crypto.params.RSAKeyParameters.validate(RSAKeyParameters.java:46)
    at com.android.org.bouncycastle.crypto.params.RSAKeyParameters.<init>(RSAKeyParameters.java:28)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePublicKeyParameter(RSAUtil.java:44)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:288)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:406)

Ответы [ 2 ]

4 голосов
/ 24 сентября 2019

Это предупреждение против катастрофы безопасности.

В RSA мы ожидаем, что составной модуль n имеет два простых множителя, близких к sqrt{n}, в противном случае, если одно простое число мало, можно легко вычислитьваш модуль в n=p q и введите ваш секретный показатель d, BOOM.

Запустите key-gen, снова.Также предпочитаю использовать публичный показатель 3, 5, 17, 257 or 65537.Это помогает иметь более быстрые вычисления.Вы использовали 17489 , что требует 4 умножения, однако 65537 требует 2 - не считая возведения в квадрат.

Также вам следует позвонить

Cipher.getInstance("RSA/ECB/PKCS1Padding");

или

Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");

not

Cipher.getInstance("RSA");

Это небезопасно, податливо и имеет много атак.

RSA - функция люка.При шифровании и подписи его никогда не следует использовать без надлежащего заполнения.

  • Для шифрования можно использовать PKCS1Padding и OAEP .OAEP - лучший выбор.
  • Для использования подписи RSA-PSS

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

также обратите внимание на то, что: На самом деле не рекомендуется использовать RSA для шифрования, в общем случае RSA используется для подписей.Мы объединяем симметричные и асимметричные схемы шифрования в Hybrid-Cryptosystem .Например, можно использовать Обмен ключами Диффи-Хеллмана , чтобы установить общий ключ с прямой секретностью , чтобы данные могли быть зашифрованы с помощью алгоритма симметричного шифрования, такого как AES, который намного быстрее, чемлюбая асимметричная криптосистема.Существует также Механизм инкапсуляции ключей (KEM) и он применим к RSA, известному как RSA-KEM, который можно использовать для установления ключа.

1 голос
/ 24 сентября 2019

Чтобы добавить к @kelalakas полный ответ, вы можете увидеть код оживленного замка, в результате которого выдается исключение здесь - соответствующая логика:

    // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
          "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
        + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
        + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
        + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
    16);

private static final BigInteger ONE = BigInteger.valueOf(1);

    if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
      {
        throw new IllegalArgumentException("RSA modulus has a small prime factor");
      }

Итак, ищитев вашем коде модуль, который вы задаете (new BigInteger(publicKeyBytes)), имеет общий множитель (и) с SMALL_PRIMES_PRODUCT.

...