Java - Хранение пар ключей в хранилище ключей - PullRequest
0 голосов
/ 13 апреля 2020

Я реализую проект гибридного шифрования и сгенерировал 2 пары ключей для ключей отправителя и получателя (private и publi c). У меня есть эти ключи в файле.

Код генерации KeyPair

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

import Decoder.BASE64Encoder;

public class GenerateRSAKeys{

    public static void main(String[] args)
    {



        String publicKeyFilename = null;
        String privateKeyFilename = null;

        publicKeyFilename = "C:\\Users\\imjme1\\Desktop\\Work_backup\\FMS\\EPM_FILE_ENCRYPTION\\NIFT_SOLUTION\\sender_keys\\receiver_publicKey";
        privateKeyFilename = "C:\\Users\\imjme1\\Desktop\\Work_backup\\FMS\\EPM_FILE_ENCRYPTION\\NIFT_SOLUTION\\sender_keys\\receiver_privateKey";

        GenerateRSAKeys generateRSAKeys = new GenerateRSAKeys();

        generateRSAKeys.generate(publicKeyFilename, privateKeyFilename);

    }

    private void generate (String publicKeyFilename, String privateFilename){

        try {

            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            // Create the public and private keys
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            BASE64Encoder b64 = new BASE64Encoder();

            SecureRandom random = createFixedRandom();
            generator.initialize(1024, random);

            KeyPair pair = generator.generateKeyPair();
            Key pubKey = pair.getPublic();
            Key privKey = pair.getPrivate();

            System.out.println("publicKey : " + b64.encode(pubKey.getEncoded()));
            System.out.println("privateKey : " + b64.encode(privKey.getEncoded()));

            BufferedWriter out = new BufferedWriter(new FileWriter(publicKeyFilename));
            out.write(b64.encode(pubKey.getEncoded()));
            out.close();

            out = new BufferedWriter(new FileWriter(privateFilename));
            out.write(b64.encode(privKey.getEncoded()));
            out.close();


        }
        catch (Exception e) {
            System.out.println(e);
        }
    }

    public static SecureRandom createFixedRandom()
    {
        return new FixedRand();
    }

    private static class FixedRand extends SecureRandom {

        MessageDigest sha;
        byte[] state;

        FixedRand() {
            try
            {
                this.sha = MessageDigest.getInstance("SHA-1");
                this.state = sha.digest();
            }
            catch (NoSuchAlgorithmException e)
            {
                throw new RuntimeException("can't find SHA-1!");
            }
        }

        public void nextBytes(byte[] bytes){

            int    off = 0;

            sha.update(state);

            while (off < bytes.length)
            {                
                state = sha.digest();

                if (bytes.length - off > state.length)
                {
                    System.arraycopy(state, 0, bytes, off, state.length);
                }
                else
                {
                    System.arraycopy(state, 0, bytes, off, bytes.length - off);
                }

                off += state.length;

                sha.update(state);
            }
        }
    }

}

Теперь мне нужно защитить эти ключи (вероятно, не на любом диске напрямую).

Я искал это дело в интернете; сохранение ключей в хранилищах ключей - это способ защитить ключи и использовать одно и то же хранилище ключей при чтении ключей для использования при шифровании и дешифровании.

Может кто-нибудь подсказать мне, как сохранить публичные c и закрытый ключ в хранилище ключей и как это читать в java?

1 Ответ

0 голосов
/ 03 мая 2020

Java KeyStore API (и соответствующие провайдеры) не поддерживает сохранение пары ключей - то есть privatekey и publickey ( который затем может быть использован для операций publickey, таких как шифрование и проверка). Он поддерживает хранение приватного ключа и цепочки сертификатов для публичного ключа. Цепочка сертификатов может состоять только из одного сертификата, особенно если этот сертификат является самозаверяющим сертификатом (который по определению является цепочкой сам по себе). Именно это и делает командная строка keytool -genkeypair: она генерирует пару ключей и сохраняет приватный ключ и самозаверяющий сертификат для публичного ключа в (указанном или заданном по умолчанию) файле хранилища ключей.

Если вы использовали только «стандартную» JRE, создать самоподписанный (или другой) сертификат в коде не очень просто.

Однако, если вы добавили BouncyCastle, как вы, очевидно, делаете, или код, который вы опубликовали, не будет работать, он имеет множество применимых возможностей. Простой пример генерации сертификата только с bcprov (старый устаревший X509V3CertificateGenerator) см. В моем API JAVA для создания хранилища ключей и присоединения к нему csr и пары ключей - но делайте так, как я рекомендовал, но не показывали: сначала не создавайте ненужный CSR, вместо этого создайте сертификат, используя желаемое имя и publickey.

Лучше, если у вас также есть или вы можете получить bcpkix, используйте X509v3CertificateBuilder. См. Примеры в Самоподписанный сертификат X509 с Bouncy Castle в Java и Создание сертификата X509 с использованием Bouncy Castle Java.

Для записи и считывания файла хранилища ключей, содержащего эти данные, просто см. Javado c, связанный выше. Обратите внимание, что Java традиционно используется по умолчанию в файлах формата JKS, и вы найдете много более старых ответов здесь и в других местах в Интернете, которые предполагают, что, но с Java 9 в 2017 году по умолчанию используется формат PKCS12, который является не только стандартным и таким образом (в основном) совместимый, но также более безопасный (использует намного лучший алгоритм PBKDF).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...