001package com.box.sdk; 002 003import java.io.IOException; 004import java.io.StringReader; 005import java.security.PrivateKey; 006import java.security.Security; 007import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 008import org.bouncycastle.jce.provider.BouncyCastleProvider; 009import org.bouncycastle.openssl.PEMDecryptorProvider; 010import org.bouncycastle.openssl.PEMEncryptedKeyPair; 011import org.bouncycastle.openssl.PEMKeyPair; 012import org.bouncycastle.openssl.PEMParser; 013import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; 014import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; 015import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; 016import org.bouncycastle.operator.InputDecryptorProvider; 017import org.bouncycastle.operator.OperatorCreationException; 018import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; 019import org.bouncycastle.pkcs.PKCSException; 020 021/** 022 * The default implementation of `IPrivateKeyDecryptor`, which uses Bouncy Castle library to decrypt 023 * the private key. 024 */ 025public class BCPrivateKeyDecryptor implements IPrivateKeyDecryptor { 026 027 /** 028 * Decrypts private key with provided passphrase using Bouncy Castle library 029 * 030 * @param encryptedPrivateKey Encoded private key string. 031 * @param passphrase Private key passphrase. 032 * @return java.security.PrivateKey instance representing decrypted private key. 033 */ 034 @Override 035 public PrivateKey decryptPrivateKey(String encryptedPrivateKey, String passphrase) { 036 Security.addProvider(new BouncyCastleProvider()); 037 PrivateKey decryptedPrivateKey; 038 try { 039 PEMParser keyReader = new PEMParser(new StringReader(encryptedPrivateKey)); 040 Object keyPair = keyReader.readObject(); 041 keyReader.close(); 042 043 if (keyPair instanceof PrivateKeyInfo) { 044 PrivateKeyInfo keyInfo = (PrivateKeyInfo) keyPair; 045 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 046 } else if (keyPair instanceof PEMEncryptedKeyPair) { 047 JcePEMDecryptorProviderBuilder builder = new JcePEMDecryptorProviderBuilder(); 048 PEMDecryptorProvider decryptionProvider = builder.build(passphrase.toCharArray()); 049 keyPair = ((PEMEncryptedKeyPair) keyPair).decryptKeyPair(decryptionProvider); 050 PrivateKeyInfo keyInfo = ((PEMKeyPair) keyPair).getPrivateKeyInfo(); 051 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 052 } else if (keyPair instanceof PKCS8EncryptedPrivateKeyInfo) { 053 InputDecryptorProvider pkcs8Prov = 054 new JceOpenSSLPKCS8DecryptorProviderBuilder() 055 .setProvider("BC") 056 .build(passphrase.toCharArray()); 057 PrivateKeyInfo keyInfo = 058 ((PKCS8EncryptedPrivateKeyInfo) keyPair).decryptPrivateKeyInfo(pkcs8Prov); 059 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 060 } else { 061 PrivateKeyInfo keyInfo = ((PEMKeyPair) keyPair).getPrivateKeyInfo(); 062 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 063 } 064 } catch (IOException e) { 065 throw new BoxAPIException("Error parsing private key for Box Developer Edition.", e); 066 } catch (OperatorCreationException e) { 067 throw new BoxAPIException("Error parsing PKCS#8 private key for Box Developer Edition.", e); 068 } catch (PKCSException e) { 069 throw new BoxAPIException("Error parsing PKCS private key for Box Developer Edition.", e); 070 } 071 return decryptedPrivateKey; 072 } 073}