InvalidKeyException: спецификация ключа не распознана

1

Я получаю

InvalidKeyException: недопустимый размер ключа или параметры по умолчанию

при попытке запустить веб-приложение, которое является развернутой WAR. Я размещаю его на Tomcat в среде Linux. Я уже поместил два файла UnlimitedJCEPolicy в пункт назначения /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.55.x86_64/jre/lib/security, и кажется, что ошибка все еще происходит. Обратите внимание, что это происходит только при запуске в среде linux. Локально он работает нормально. Вот мой код:

public static final void decryptFile(File inputFile, File outputFile) throws 
IOException, PGPException {
    // Add Bouncy Castle provider
    Security.addProvider(new BouncyCastleProvider());

    // Grab secret key that in folder with AE classes
    Resource resource = new ClassPathResource(Env.getSecretKeyAE());
    log.debug("Resource: " + Env.getSecretKeyAE());
    File keyFileName = resource.getFile();
    log.debug("Key File Name: " + keyFileName);
    // Decryption password
    String pass = "pass";
    char[] passwd = pass.toCharArray();

    // Read files into streams
    log.info("Reading files into streams");
    InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
    InputStream in = PGPUtil.getDecoderStream(new BufferedInputStream(new 
FileInputStream(inputFile)));

    // I don't even know what these do
    PGPObjectFactory pgpObjFactory = new PGPObjectFactory(in);
    PGPEncryptedDataList pgpEncryptedDataList = null;

    Object o = pgpObjFactory.nextObject();
    log.info("Checking instance of PGPEncryptedDataList");
    if (o instanceof PGPEncryptedDataList) {
        pgpEncryptedDataList = (PGPEncryptedDataList)o;
    }
    else {
        pgpEncryptedDataList = (PGPEncryptedDataList)pgpObjFactory.nextObject();
    }

    // This will be the PGPPrivateKey we use to decrypt
    log.info("Initializing secret key");
    PGPPrivateKey secretKey = null;
    PGPPublicKeyEncryptedData publicKeyEncryptedData = null;
    PGPSecretKeyRingCollection pgpSecretKeyRingCollection = new    
PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn));

    // This iterates the key file as if it has many keys, this file has only one
    // This is the only way I could find to construct a PGPPrivateKey
    log.info("Iterating through key file");
    Iterator<?> it = pgpEncryptedDataList.getEncryptedDataObjects();
    while(it.hasNext() && secretKey == null) {
        publicKeyEncryptedData = (PGPPublicKeyEncryptedData) it.next();
        PGPSecretKey pgpSecKey = 
pgpSecretKeyRingCollection.getSecretKey(publicKeyEncryptedData.getKeyID());

        if (pgpSecKey != null) {
            Provider provider = Security.getProvider("BC");
            secretKey = pgpSecKey.extractPrivateKey(new   

JcePBESecretKeyDecryptorBuilder(new  
JcaPGPDigestCalculatorProviderBuilder().setProvider(provider)
.build()).setProvider(provider).build(passwd));
           }
    }
    log.info("PGPPrivateKey has been constructed");
    if (secretKey == null) {
        throw new IllegalArgumentException("secret key for message not found.");
    }
    log.info("Secret Key found!");

    if(publicKeyEncryptedData == null) {
        throw new NullPointerException("cannot continue with null public key encryption 
data.");
    }
    log.info("Public Key Encrypted Data found!");

    // More stuff I don't fully understand, I think this is just standard way to   
decrypt files once the above is all set up
    log.info("Starting actual decryption");
    //get data stream where our publicKeyDataDecrypterFactory sets ours provider to BC 
and we build our secretKey
    //secretkey is our PGPPrivateKey

    log.info("start");

    //=====================================================================
    //ERROR IS OCCURRING HERE
    InputStream clear = publicKeyEncryptedData.getDataStream(new  
JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(secretKey));
    log.info("1");
    PGPObjectFactory plainFact = new PGPObjectFactory(clear);
    log.info("2");
    PGPCompressedData compressedData = (PGPCompressedData)plainFact.nextObject();
    log.info("3");
    InputStream compressedStream = new 
BufferedInputStream(compressedData.getDataStream());
    log.info("4");
    PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream);
    log.info("5");
    Object message = pgpFact.nextObject();
    log.info("6");

    if (message instanceof PGPLiteralData) {
        log.info("Our message is an instance of PGP Literal Data.");
        PGPLiteralData literalData = (PGPLiteralData)message;
        InputStream literalDataInputStream = literalData.getInputStream();
        OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
        Streams.pipeAll(literalDataInputStream, out);
        out.close();
    }
    else if (message instanceof PGPOnePassSignatureList) {
        log.error("encrypted message contains a signed message - not literal data.");
        throw new PGPException("encrypted message contains a signed message - not  

literal data.");
    }
    else {
        log.error("message is not a simple encrypted file - type unknown.");
        throw new PGPException("message is not a simple encrypted file - type  
unknown.");
    }
    log.info("Checking if public key encrypted data is integrity protected");
    if (publicKeyEncryptedData.isIntegrityProtected()) {
        if (!publicKeyEncryptedData.verify()) {
            throw new PGPException("message failed integrity check");
        }
    }

    keyIn.close();
    in.close();
}

Используя журналы, я смог найти, что ошибка произошла, когда

InputStream clear = publicKeyEncryptedData.getDataStream(new  
JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(secretKey));

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

EDIT Я исправил проблему с нелегальным размером ключа, но теперь я получаю "ключ не распознан",

EDIT Дополнительная информация об ошибке "ключевая спецификация не распознана": Итак, как я уже сказал, размер нелегального ключа ушел, но "ключевая спецификация не распознана", похоже, еще проблема. Странно, что мой метод encryptFile работает отлично, но decryptFile бросает ошибку. Я не совсем понимаю, почему. Прежде чем я ушел с работы, я проверил еще раз, и кажется, что ошибка не была выбрана. Кажется, что эта ошибка возникает случайно в зависимости от развертывания WAR для tomcat. Если я развожу свою WAR, ошибка не будет возникать в некоторых точках, но если я развёртываю и передислоцирую с обновленным файлом WAR, возникает ошибка. Я не знаю, что вызывает это, и основанные на исследованиях, которые никто действительно не знает. По-видимому, это было ошибкой в Bouncy Castle до 1.5, но 1.5 - это версия, в которой я запускаю, чтобы не проблема. Я отправлю сообщение, если найду что-нибудь, что может исправить эту ошибку.

  • 0
    Поскольку я использовал Tomcat, мой Java-дом находился в папке opt. Точное местоположение, в которое я должен был поместить файлы UnlimitedJCEPolicy, было /opt/jre1.7.0_60/lib/security. После размещения файлов и повторного развертывания моего военного файла я больше не испытывал этой проблемы.
Теги:
bouncycastle
pgp

3 ответа

0
Лучший ответ

Чтобы предотвратить ошибку "Недопустимый размер ключа или параметры по умолчанию", я просто должен был поместить файлы UnlimitedJCEPolicy в свой рабочий каталог java,/opt/jre1.7.0_60/lib/security. После размещения файлов и повторного развертывания моего военного файла я больше не испытывал этой проблемы.

Чтобы предотвратить ошибку "key spec not detected", мне пришлось перезапустить мой сервер tomcat при перераспределении моего WAR файла.

1

Решать:

java.security.spec.InvalidKeySpecException: ключ не распознан

Изменить поставщиков безопасности:

sudo nano $JAVA_HOME/jre/lib/security/java.security

Добавить поставщика безопасности:

security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

Скопируйте bcprov-jdk15on-1.54.jar в:

$JAVA_HOME/jre/lib/ext/bcprov-jdk15on-1.54.jar

Перезапустите Tomcat.

0
if (o instanceof PGPEncryptedDataList) {
        pgpEncryptedDataList = (PGPEncryptedDataList)o;

если o уже является экземпляром PGPEncryptedDataList, почему вы отсылаете его в PGPEncryptedDataLIST?

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

  • 0
    Если честно, это был бывший сотрудник, поэтому я сам не могу даже сказать, почему это так. Спасибо, что обратили на это мое внимание!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню