2015-12-20 3 views
1

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

java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. 
at sun.security.util.DerInputStream.getLength(DerInputStream.java:561) 
at sun.security.util.DerValue.init(DerValue.java:365) 
at sun.security.util.DerValue.<init>(DerValue.java:294) 
at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:84) ... 

Это, как я шифровать и запись в файл закрытого ключа:

public static void savePrivateKeyToDisk(PrivateKey privateKey, String passord){ 

    try { 
     // unencrypted PKCS#8 private key 
     byte[] encodedPrivateKey = privateKey.getEncoded(); 

     String MYPBEALG = "PBEWithSHA1AndDESede"; 

     int count = 20; 
     SecureRandom random = new SecureRandom(); 
     byte[] salt = new byte[8]; 
     random.nextBytes(salt); 

     // Create PBE parameter set 
     PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count); 
     PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); 
     SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG); 
     SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); 

     Cipher pbeCipher = Cipher.getInstance(MYPBEALG); 

     // Initialize PBE Cipher with key and parameters 
     pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); 

     // Encrypt the encoded Private Key with the PBE key 
     byte[] cipherText = pbeCipher.doFinal(encodedPrivateKey); 

     // Now construct PKCS #8 EncryptedPrivateKeyInfo object 
     AlgorithmParameters algparms = AlgorithmParameters.getInstance(MYPBEALG); 
     algparms.init(pbeParamSpec); 
     EncryptedPrivateKeyInfo encinfo = new EncryptedPrivateKeyInfo(algparms, cipherText); 

     // DER encoded PKCS#8 encrypted key 
     byte[] encryptedPkcs8 = encinfo.getEncoded(); 


     File encryptedPrivate = new File(PRIVATE_KEY_FILE); 

     if (encryptedPrivate.getParentFile() != null) { 
      encryptedPrivate.getParentFile().mkdirs(); 
     } 
     encryptedPrivate.createNewFile(); 

     ObjectOutputStream publicKeyOS = new ObjectOutputStream(
       new FileOutputStream(encryptedPrivate)); 
     publicKeyOS.writeObject(encryptedPkcs8); 
     publicKeyOS.close(); 

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

... и это, как я пытаюсь прочитать зашифрованный секретный ключ:

public static PrivateKey getPrivateKey(String passwd){ 
    try { 

     byte[] encodedPrivateKey = getFileBytes(PRIVATE_KEY_FILE); 

     // exception thrown from here 
     EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(encodedPrivateKey); 

     Cipher cipher = Cipher.getInstance(encryptPKInfo.getAlgName()); 
     PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray()); 
     SecretKeyFactory secFac = SecretKeyFactory.getInstance(encryptPKInfo.getAlgName()); 
     Key pbeKey = secFac.generateSecret(pbeKeySpec); 
     AlgorithmParameters algParams = encryptPKInfo.getAlgParameters(); 
     cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams); 
     KeySpec pkcs8KeySpec = encryptPKInfo.getKeySpec(cipher); 
     KeyFactory kf = KeyFactory.getInstance(ALGORITHM); 
     return kf.generatePrivate(pkcs8KeySpec); 
    } 
    catch (Exception e){ 
     e.printStackTrace(); 
     return null; 
    } 
} 

... метод getFileBytes:

private static byte[] getFileBytes(String infile){ 
    File f = new File(infile) ; 
    int sizecontent = ((int) f.length()); 
    byte[] data = new byte[sizecontent]; 
    try 
    { 
     FileInputStream freader = new FileInputStream(f); 
     freader.read(data, 0, sizecontent) ; 
     freader.close(); 
     return data; 
    } 
    catch(IOException ioe) 
    { 
     System.out.println(ioe.toString()); 
     return null; 
    } 
} 

Похоже, зашифрованный закрытый ключ не в нужном формате, но сохранить его в DER PKCS формата # 8. Итак, вопрос: Какая ошибка в этом коде?

+0

Асимметричное шифрование не предназначена для encryp которые больше размера ключа. – m0skit0

ответ

0

Я думаю, проблема в том, что вы пишете Object, но тогда вы читаете byte[] (не Object) Я хотел бы предложить, что вы либо прочитать весь объект, а затем получить необходимые байты или даже лучше писать byte[] непосредственно (дон «т использовать ObjectOutputStream), а затем загрузить эти байты, например:

FileOutputStream fos = new FileOutputStream(PRIVATE_KEY_FILE); 
fos.write(myByteArray); 
fos.close(); 

, а затем получить его:

byte[] bytes = Files.readAllBytes(Paths.get(PRIVATE_KEY_FILE)); 
+0

Конструктор 'EncryptedPrivateKeyInfo' по-прежнему генерирует исключение, и это' java.io.IOException: DerValue.getOctetString, а не октетная строка: 3'. Теперь я пишу 'FileOutputStream fos = new FileOutputStream (PRIVATE_KEY_FILE); fos.write (encryptedPkcs8); fos.close(); 'и чтение' byte [] bytes = Files.readAllBytes (Paths.get (PRIVATE_KEY_FILE)); EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo (bytes); ' –

+0

Метод DerValue.getOctetString' ожидает тег Octet String, но он получает тег бит строки. –

+0

Работал наконец! –