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 the private key. 023 */ 024public class BCPrivateKeyDecryptor implements IPrivateKeyDecryptor { 025 026 /** 027 * Decrypts private key with provided passphrase using Bouncy Castle library 028 * 029 * @param encryptedPrivateKey Encoded private key string. 030 * @param passphrase Private key passphrase. 031 * @return java.security.PrivateKey instance representing decrypted private key. 032 */ 033 @Override 034 public PrivateKey decryptPrivateKey(String encryptedPrivateKey, String passphrase) { 035 Security.addProvider(new BouncyCastleProvider()); 036 PrivateKey decryptedPrivateKey; 037 try { 038 PEMParser keyReader = new PEMParser(new StringReader(encryptedPrivateKey)); 039 Object keyPair = keyReader.readObject(); 040 keyReader.close(); 041 042 if (keyPair instanceof PrivateKeyInfo) { 043 PrivateKeyInfo keyInfo = (PrivateKeyInfo) keyPair; 044 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 045 } else if (keyPair instanceof PEMEncryptedKeyPair) { 046 JcePEMDecryptorProviderBuilder builder = new JcePEMDecryptorProviderBuilder(); 047 PEMDecryptorProvider decryptionProvider = builder.build(passphrase.toCharArray()); 048 keyPair = ((PEMEncryptedKeyPair) keyPair).decryptKeyPair(decryptionProvider); 049 PrivateKeyInfo keyInfo = ((PEMKeyPair) keyPair).getPrivateKeyInfo(); 050 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 051 } else if (keyPair instanceof PKCS8EncryptedPrivateKeyInfo) { 052 InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder() 053 .setProvider("BC") 054 .build(passphrase.toCharArray()); 055 PrivateKeyInfo keyInfo = ((PKCS8EncryptedPrivateKeyInfo) keyPair).decryptPrivateKeyInfo(pkcs8Prov); 056 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 057 } else { 058 PrivateKeyInfo keyInfo = ((PEMKeyPair) keyPair).getPrivateKeyInfo(); 059 decryptedPrivateKey = (new JcaPEMKeyConverter()).getPrivateKey(keyInfo); 060 } 061 } catch (IOException e) { 062 throw new BoxAPIException("Error parsing private key for Box Developer Edition.", e); 063 } catch (OperatorCreationException e) { 064 throw new BoxAPIException("Error parsing PKCS#8 private key for Box Developer Edition.", e); 065 } catch (PKCSException e) { 066 throw new BoxAPIException("Error parsing PKCS private key for Box Developer Edition.", e); 067 } 068 return decryptedPrivateKey; 069 } 070}