Зашифруйте и расшифруйте SecretKey с помощью открытых и закрытых ключей RSA.

Я пытаюсь зашифровать секретный ключ своим открытым ключом, а затем расшифровать его в другом месте с помощью закрытого ключа. Я могу нормально шифровать и расшифровывать, однако, когда я это делаю, я получаю совершенно другой ключ.

Вот код, который создает пару открытого/закрытого ключей

public static KeyPair generateKeyPair()
{
    KeyPair returnPair = null;
    try
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunJSSE");

        System.out.println("provider:" + kpg.getProvider().getName());

        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

        kpg.initialize(1024, random);

        returnPair = kpg.generateKeyPair();

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return returnPair;
}

Я указал провайдера SunJSSE, хотя результат не отличается от результатов, полученных при запуске с DiffieHellman из SunJCE или провайдера RSA/SunRSASign. Я новичок в безопасности Java, поэтому эти концепции все еще немного выше моей головы.

Вот код, который я использую для генерации секретного ключа

    public static SecretKey generateSecretKey(String keyPassword)
{
    SecretKey key = null;
    try
    {
        SecretKeyFactory method = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

        //System.out.println("salt length: " + new SaltIVManager().getSalt().length);

        PBEKeySpec spec = new PBEKeySpec(keyPassword.toCharArray(), new SaltIVManager().getSalt(), 10000, 128);

        key = method.generateSecret(spec);

        System.out.println("generate secret key length: " + key.getEncoded().length); 

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return key;
}

И вот два метода, которые я использую для шифрования/дешифрования моего секретного ключа.

    public static byte[] encryptSecretKey(SecretKey secretKey, PublicKey publicKey)
{
    byte[] encryptedSecret = null;
    try
    {

        Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");

        System.out.println("provider: " + cipher.getProvider().getName());

        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        System.out.println("original secret key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()) + " \n secretkey encoded length: " + secretKey.getEncoded().length);

        encryptedSecret = cipher.doFinal(secretKey.getEncoded());


        System.out.println("encrypted secret: " + Base64.getEncoder().encodeToString(encryptedSecret)); 

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return encryptedSecret;
}



public static SecretKey decryptSecretKey(byte[] encryptedKey, PrivateKey privateKey)
{
    SecretKey returnKey = null;
    try
    {
        Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");

        System.out.println("provider: " + cipher.getProvider().getName());

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        System.out.println("encryptedkey length: " + encryptedKey.length);

        byte [] encodedSecret = cipher.doFinal(encryptedKey);

        System.out.println("encoded Secret after decrypt: " + Base64.getEncoder().encodeToString(encodedSecret));

        returnKey = new SecretKeySpec(encodedSecret, 0, encodedSecret.length, "PBEWithMD5AndDES");

        System.out.println("secret key: " + Base64.getEncoder().encodeToString(returnKey.getEncoded()));

        System.out.println("secret key length post decrypt: " + returnKey.getEncoded().length);
    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return returnKey;
}

Алгоритм RSA — единственный, который я заставил работать с моими ключами. Если я укажу алгоритм DiffieHellman. для пары ключей я вообще не могу шифровать/дешифровать. Если у кого-то есть понимание того, что я сделал неправильно, любая помощь будет принята с благодарностью. Когда я вызываю это в его текущем состоянии, я начинаю с секретного ключа этого значения = cGFzczEyMw== и заканчиваю ключом этого значения после шифрования/дешифрования

SvMNufKu2JA4hnNEwuWdOgJu6FxnNmuLYzxENhTsGgFzc / i3kQIXbeVaJUkJck918BLCnm2u2QZCyVvJjYFXMLBFga0Zq0WMxSbIZvPz1J / EDi9dpsAkbFhLyBWmdDyPr + w7DMDsqHwKuA8y / IRKVINWXVrp3Hbt8goFZ0nGIlKVzMdJbGhNi3HZSAw4R6fXZNKOJ3nN6wDldzYerEaz2MhJqnZ3Dz4psA6gskomhjp / G0yhsGO8pllMcgD0jzhL86RGrBhjj04Bj0ps3AAACkQLcCwisso8dWigvR8NX9dnI0C / gc6FqmNenWI1 / AoPgmcRyFdlO7A2i9JXoSj + YQ ==


person SteveManC    schedule 01.03.2016    source источник


Ответы (2)


Сначала вы должны знать, что вы пытаетесь сделать, прежде чем делать это:

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

Весь протокол не имеет смысла. То, что вы пытаетесь зашифровать напрямую с помощью DH (схема согласования ключей), показывает, что вы недостаточно изучили криптографию.

С криптографией дело не в том, чтобы заставить что-то работать. Речь идет об обеспечении безопасности. Вы не можете сделать это, просто пробуя вещи. Изучите хотя бы основы криптографии, затем программируйте.

person Maarten Bodewes    schedule 01.03.2016
comment
Я использовал пароль для PBE, а не ключ, как вы предложили выше. У меня никогда не было ключа DES, поэтому я не уверен, где вы это видите. Кроме того, я не шифровал/дешифровал с помощью DH, как вы предложили, хотя пытался получить рабочий ключ из этого алгоритма. Код показывает именно то, что я пытался. Я считаю, что это все основные понятия. - person SteveManC; 02.03.2016
comment
Моя ошибка. Спасибо - person SteveManC; 02.03.2016

На самом деле проблема заключалась в том, как я хранил/извлекал свои ключи. Я использовал хранилище ключей для частного и файл для публики. Способ, которым я получил эти ключи, приводил к их искажению, таким образом, сбой в моем шифре и необходимость работать с NOPADDING, чтобы получить какой-либо вывод. Вот новый код хранения, который я использую для ключей RSA — запись их в файл.

    public static boolean saveKeys(Key privateKey, Key publicKey, char[] password, String alias)
{
    boolean saved = false;
    try
    {
        KeyPair kp = generateKeyPair();


        KeyFactory kf = KeyFactory.getInstance("RSA");

        if(privateKey != null)
        {

            File privKeyFile = new File(System.getProperty("user.home") + "/.etc/privkey");

            if(!privKeyFile.exists())
            {
                privKeyFile.createNewFile();
            }

            System.out.println("private key: " + Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded()));

            RSAPrivateKeySpec pubSpec = kf.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);

            ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/privkey")));

            oout.writeObject(pubSpec.getModulus());

            oout.writeObject(pubSpec.getPrivateExponent());

            oout.close();


        }if(publicKey != null)
        {

            File pubKeyFile = new File(System.getProperty("user.home") + "/.etc/pubkey.pub");

            if(!pubKeyFile.exists())
            {
                pubKeyFile.createNewFile();
            }

            System.out.println("public key: " + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()));

            RSAPublicKeySpec pubSpec = kf.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);

            ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/pubkey.pub")));

            oout.writeObject(pubSpec.getModulus());

            oout.writeObject(pubSpec.getPublicExponent());

            oout.close();

        }



    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return saved;
}
person SteveManC    schedule 02.03.2016