1 package org.bouncycastle.crypto.util; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 7 import org.bouncycastle.asn1.DERNull; 8 import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 9 import org.bouncycastle.asn1.gm.GMObjectIdentifiers; 10 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; 11 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 12 import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; 13 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 14 import org.bouncycastle.util.Integers; 15 16 /** 17 * Configuration class for a PBKDF using PKCS#5 Scheme 2. 18 */ 19 public class PBKDF2Config 20 extends PBKDFConfig 21 { 22 /** 23 * AlgorithmIdentifier for a PRF using HMac with SHA-1 24 */ 25 public static final AlgorithmIdentifier PRF_SHA1 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE); 26 27 /** 28 * AlgorithmIdentifier for a PRF using HMac with SHA-256 29 */ 30 public static final AlgorithmIdentifier PRF_SHA256 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE); 31 32 /** 33 * AlgorithmIdentifier for a PRF using HMac with SHA-512 34 */ 35 public static final AlgorithmIdentifier PRF_SHA512 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE); 36 37 /** 38 * AlgorithmIdentifier for a PRF using HMac with SHA3-256 39 */ 40 public static final AlgorithmIdentifier PRF_SHA3_256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_256, DERNull.INSTANCE); 41 42 /** 43 * AlgorithmIdentifier for a PRF using SHA3-512 44 */ 45 public static final AlgorithmIdentifier PRF_SHA3_512 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_512, DERNull.INSTANCE); 46 47 private static final Map PRFS_SALT = new HashMap(); 48 49 static 50 { PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA1, Integers.valueOf(20))51 PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA1, Integers.valueOf(20)); PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA256, Integers.valueOf(32))52 PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA256, Integers.valueOf(32)); PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA512, Integers.valueOf(64))53 PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA512, Integers.valueOf(64)); PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA224, Integers.valueOf(28))54 PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA224, Integers.valueOf(28)); PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA384, Integers.valueOf(48))55 PRFS_SALT.put(PKCSObjectIdentifiers.id_hmacWithSHA384, Integers.valueOf(48)); PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, Integers.valueOf(28))56 PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, Integers.valueOf(28)); PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, Integers.valueOf(32))57 PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, Integers.valueOf(32)); PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, Integers.valueOf(48))58 PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, Integers.valueOf(48)); PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(64))59 PRFS_SALT.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(64)); PRFS_SALT.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(32))60 PRFS_SALT.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(32)); PRFS_SALT.put(RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256, Integers.valueOf(32))61 PRFS_SALT.put(RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256, Integers.valueOf(32)); PRFS_SALT.put(RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512, Integers.valueOf(64))62 PRFS_SALT.put(RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512, Integers.valueOf(64)); PRFS_SALT.put(GMObjectIdentifiers.hmac_sm3, Integers.valueOf(32))63 PRFS_SALT.put(GMObjectIdentifiers.hmac_sm3, Integers.valueOf(32)); 64 } 65 getSaltSize(ASN1ObjectIdentifier algorithm)66 static int getSaltSize(ASN1ObjectIdentifier algorithm) 67 { 68 if (!PRFS_SALT.containsKey(algorithm)) 69 { 70 throw new IllegalStateException("no salt size for algorithm: " + algorithm); 71 } 72 73 return ((Integer)PRFS_SALT.get(algorithm)).intValue(); 74 } 75 76 public static class Builder 77 { 78 private int iterationCount = 1024; 79 private int saltLength = -1; 80 private AlgorithmIdentifier prf = PRF_SHA1; 81 82 /** 83 * Base constructor. 84 * 85 * This configures the builder to use an iteration count of 1024, and the HMacSHA1 PRF. 86 */ Builder()87 public Builder() 88 { 89 } 90 91 /** 92 * Set the iteration count for the PBE calculation. 93 * 94 * @param iterationCount the iteration count to apply to the key creation. 95 * @return the current builder. 96 */ withIterationCount(int iterationCount)97 public Builder withIterationCount(int iterationCount) 98 { 99 this.iterationCount = iterationCount; 100 101 return this; 102 } 103 104 /** 105 * Set the PRF to use for key generation. By default this is HmacSHA1. 106 * 107 * @param prf algorithm id for PRF. 108 * @return the current builder. 109 */ withPRF(AlgorithmIdentifier prf)110 public Builder withPRF(AlgorithmIdentifier prf) 111 { 112 this.prf = prf; 113 114 return this; 115 } 116 117 /** 118 * Set the length of the salt to use. 119 * 120 * @param saltLength the length of the salt (in octets) to use. 121 * @return the current builder. 122 */ withSaltLength(int saltLength)123 public Builder withSaltLength(int saltLength) 124 { 125 this.saltLength = saltLength; 126 127 return this; 128 } 129 build()130 public PBKDF2Config build() 131 { 132 return new PBKDF2Config(this); 133 } 134 } 135 136 private final int iterationCount; 137 private final int saltLength; 138 private final AlgorithmIdentifier prf; 139 PBKDF2Config(Builder builder)140 private PBKDF2Config(Builder builder) 141 { 142 super(PKCSObjectIdentifiers.id_PBKDF2); 143 144 this.iterationCount = builder.iterationCount; 145 this.prf = builder.prf; 146 147 if (builder.saltLength < 0) 148 { 149 this.saltLength = getSaltSize(prf.getAlgorithm()); 150 } 151 else 152 { 153 this.saltLength = builder.saltLength; 154 } 155 } 156 getIterationCount()157 public int getIterationCount() 158 { 159 return iterationCount; 160 } 161 getPRF()162 public AlgorithmIdentifier getPRF() 163 { 164 return prf; 165 } 166 getSaltLength()167 public int getSaltLength() 168 { 169 return saltLength; 170 } 171 } 172