public static final Digest createHash(int hashAlgorithm) { switch (hashAlgorithm) { case HashAlgorithm.md5: return new MD5Digest(); case HashAlgorithm.sha1: return new SHA1Digest(); case HashAlgorithm.sha224: return new SHA224Digest(); case HashAlgorithm.sha256: return new SHA256Digest(); case HashAlgorithm.sha384: return new SHA384Digest(); case HashAlgorithm.sha512: return new SHA512Digest(); default: throw new IllegalArgumentException("unknown HashAlgorithm"); } }
static byte[] calculateKeyId(SubjectPublicKeyInfo info) { Digest dig = new SHA1Digest(); // TODO: include definition of SHA-1 here byte[] hash = new byte[dig.getDigestSize()]; byte[] spkiEnc = new byte[0]; try { spkiEnc = info.getEncoded(ASN1Encoding.DER); } catch (IOException e) { return new byte[0]; } // try the outlook 2010 calculation dig.update(spkiEnc, 0, spkiEnc.length); dig.doFinal(hash, 0); return hash; }
public DigestCalculator get(final AlgorithmIdentifier algorithm) throws OperatorCreationException { Digest dig = digestProvider.get(algorithm); final DigestOutputStream stream = new DigestOutputStream(dig); return new DigestCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public OutputStream getOutputStream() { return stream; } public byte[] getDigest() { return stream.getDigest(); } }; }
/** * Constructs a parameter set that uses ternary private keys (i.e. </code>polyType=SIMPLE</code>). * * @param N number of polynomial coefficients * @param q modulus * @param df number of ones in the private polynomial <code>f</code> * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false) * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method. */ public NTRUEncryptionKeyGenerationParameters(int N, int q, int df, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { super(new SecureRandom(), db); this.N = N; this.q = q; this.df = df; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE; this.hashAlg = hashAlg; init(); }
/** * Constructs a parameter set that uses product-form private keys (i.e. </code>polyType=PRODUCT</code>). * * @param N number of polynomial coefficients * @param q modulus * @param df1 number of ones in the private polynomial <code>f1</code> * @param df2 number of ones in the private polynomial <code>f2</code> * @param df3 number of ones in the private polynomial <code>f3</code> * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step * @param db number of random bits to prepend to the message * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator}) * @param minCallsR minimum number of hash calls for the IGF to make * @param minCallsMask minimum number of calls to generate the masking polynomial * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false) * @param oid three bytes that uniquely identify the parameter set * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false) * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code> */ public NTRUEncryptionKeyGenerationParameters(int N, int q, int df1, int df2, int df3, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg) { super(new SecureRandom(), db); this.N = N; this.q = q; this.df1 = df1; this.df2 = df2; this.df3 = df3; this.db = db; this.dm0 = dm0; this.c = c; this.minCallsR = minCallsR; this.minCallsMask = minCallsMask; this.hashSeed = hashSeed; this.oid = oid; this.sparse = sparse; this.fastFp = fastFp; this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT; this.hashAlg = hashAlg; init(); }
/** * Constructs a parameter set that uses product-form private keys (i.e. </code>polyType=PRODUCT</code>). * * @param N number of polynomial coefficients * @param q modulus * @param d1 number of -1's in the private polynomials <code>f</code> and <code>g</code> * @param d2 number of -1's in the private polynomials <code>f</code> and <code>g</code> * @param d3 number of -1's in the private polynomials <code>f</code> and <code>g</code> * @param B number of perturbations * @param basisType whether to use the standard or transpose lattice * @param beta balancing factor for the transpose lattice * @param normBound maximum norm for valid signatures * @param keyNormBound maximum norm for the ploynomials <code>F</code> and <code>G</code> * @param primeCheck whether <code>2N+1</code> is prime * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial}) * @param keyGenAlg <code>RESULTANT</code> produces better bases, <code>FLOAT</code> is slightly faster. <code>RESULTANT</code> follows the EESS standard while <code>FLOAT</code> is described in Hoffstein et al: An Introduction to Mathematical Cryptography. * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method. */ public NTRUSigningKeyGenerationParameters(int N, int q, int d1, int d2, int d3, int B, int basisType, double beta, double normBound, double keyNormBound, boolean primeCheck, boolean sparse, int keyGenAlg, Digest hashAlg) { super(new SecureRandom(), N); this.N = N; this.q = q; this.d1 = d1; this.d2 = d2; this.d3 = d3; this.B = B; this.basisType = basisType; this.beta = beta; this.normBound = normBound; this.keyNormBound = keyNormBound; this.primeCheck = primeCheck; this.sparse = sparse; this.keyGenAlg = keyGenAlg; this.hashAlg = hashAlg; polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT; init(); }
P11DSAContentSigner(P11CryptService cryptService, P11EntityIdentifier identityId, AlgorithmIdentifier signatureAlgId, boolean plain) throws XiSecurityException, P11TokenException { this.identityId = ParamUtil.requireNonNull("identityId", identityId); this.cryptService = ParamUtil.requireNonNull("cryptService", cryptService); this.algorithmIdentifier = ParamUtil.requireNonNull("signatureAlgId", signatureAlgId); try { this.encodedAlgorithmIdentifier = algorithmIdentifier.getEncoded(); } catch (IOException ex) { throw new XiSecurityException("could not encode AlgorithmIdentifier", ex); } this.plain = plain; String algOid = signatureAlgId.getAlgorithm().getId(); HashAlgoType hashAlgo = sigAlgHashMap.get(algOid); if (hashAlgo == null) { throw new XiSecurityException("unsupported signature algorithm " + algOid); } P11SlotIdentifier slotId = identityId.slotId(); P11Slot slot = cryptService.getSlot(slotId); if (slot.supportsMechanism(PKCS11Constants.CKM_DSA)) { this.mechanism = PKCS11Constants.CKM_DSA; Digest digest = hashAlgo.createDigest(); this.outputStream = new DigestOutputStream(digest); } else { this.mechanism = hashMechMap.get(hashAlgo).longValue(); if (!slot.supportsMechanism(this.mechanism)) { throw new XiSecurityException("unsupported signature algorithm " + algOid); } this.outputStream = new ByteArrayOutputStream(); } }
public static final Digest cloneHash(int hashAlgorithm, Digest hash) { switch (hashAlgorithm) { case HashAlgorithm.md5: return new MD5Digest((MD5Digest)hash); case HashAlgorithm.sha1: return new SHA1Digest((SHA1Digest)hash); case HashAlgorithm.sha224: return new SHA224Digest((SHA224Digest)hash); case HashAlgorithm.sha256: return new SHA256Digest((SHA256Digest)hash); case HashAlgorithm.sha384: return new SHA384Digest((SHA384Digest)hash); case HashAlgorithm.sha512: return new SHA512Digest((SHA512Digest)hash); default: throw new IllegalArgumentException("unknown HashAlgorithm"); } }
public TlsHandshakeHash commit() { int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); Digest prfHash = TlsUtils.createPRFHash(prfAlgorithm); byte[] data = buf.toByteArray(); prfHash.update(data, 0, data.length); if (prfHash instanceof TlsHandshakeHash) { TlsHandshakeHash tlsPRFHash = (TlsHandshakeHash)prfHash; tlsPRFHash.init(context); return tlsPRFHash.commit(); } this.prfAlgorithm = prfAlgorithm; this.hash = prfHash; this.buf = null; return this; }
public OAEPEncoding( AsymmetricBlockCipher cipher, Digest hash, Digest mgf1Hash, byte[] encodingParams) { this.engine = cipher; this.mgf1Hash = mgf1Hash; this.defHash = new byte[hash.getDigestSize()]; hash.reset(); if (encodingParams != null) { hash.update(encodingParams, 0, encodingParams.length); } hash.doFinal(defHash, 0); }
protected Digest createHMACDigest(int macAlgorithm) throws IOException { switch (macAlgorithm) { case MACAlgorithm._null: return null; case MACAlgorithm.hmac_md5: return new MD5Digest(); case MACAlgorithm.hmac_sha1: return new SHA1Digest(); case MACAlgorithm.hmac_sha256: return new SHA256Digest(); case MACAlgorithm.hmac_sha384: return new SHA384Digest(); case MACAlgorithm.hmac_sha512: return new SHA512Digest(); default: throw new TlsFatalAlert(AlertDescription.internal_error); } }
/** * Calculate a zero knowledge proof of x using Schnorr's signature. * The returned array has two elements {g^v, r = v-x*h} for x. */ public static BigInteger[] calculateZeroKnowledgeProof( BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, String participantId, Digest digest, SecureRandom random) { BigInteger[] zeroKnowledgeProof = new BigInteger[2]; /* Generate a random v, and compute g^v */ BigInteger vMin = ZERO; BigInteger vMax = q.subtract(ONE); BigInteger v = BigIntegers.createRandomInRange(vMin, vMax, random); BigInteger gv = g.modPow(v, p); BigInteger h = calculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h zeroKnowledgeProof[0] = gv; zeroKnowledgeProof[1] = v.subtract(x.multiply(h)).mod(q); // r = v-x*h return zeroKnowledgeProof; }
private static byte[] sign() throws Exception { RSAEngine rsa = new RSAEngine(); Digest dig = new SHA1Digest(); RSAPrivateKey privateKey = (RSAPrivateKey) getPrivate(privateKeyFilename); BigInteger big = ((RSAKey) privateKey).getModulus(); ISO9796d2Signer eng = new ISO9796d2Signer(rsa, dig, true); RSAKeyParameters rsaPriv = new RSAKeyParameters(true, big, privateKey.getPrivateExponent()); eng.init(true, rsaPriv); eng.update(message[0]); eng.update(message, 1, message.length - 1); byte[] signature = eng.generateSignature(); return signature; }
private static int getByteLength( Digest digest) { if (digest instanceof ExtendedDigest) { return ((ExtendedDigest)digest).getByteLength(); } Integer b = (Integer)blockLengths.get(digest.getAlgorithmName()); if (b == null) { throw new IllegalArgumentException("unknown digest passed: " + digest.getAlgorithmName()); } return b.intValue(); }
/** * create an AuthorityKeyIdentifier with the GeneralNames tag and * the serial number provided as well. */ public AuthorityKeyIdentifier( SubjectPublicKeyInfo spki, GeneralNames name, BigInteger serialNumber) { Digest digest = new SHA1Digest(); byte[] resBuf = new byte[digest.getDigestSize()]; byte[] bytes = spki.getPublicKeyData().getBytes(); digest.update(bytes, 0, bytes.length); digest.doFinal(resBuf, 0); this.keyidentifier = new DEROctetString(resBuf); this.certissuer = GeneralNames.getInstance(name.toASN1Primitive()); this.certserno = new ASN1Integer(serialNumber); }
protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) throws OperatorCreationException { if (!AlgorithmUtil.isECSigAlg(sigAlgId)) { throw new OperatorCreationException( "the given algorithm is not a valid EC signature algorithm '" + sigAlgId.getAlgorithm().getId() + "'"); } Digest dig = digestProvider.get(digAlgId); ECDSASigner dsaSigner = new ECDSASigner(); return plain ? new DSAPlainDigestSigner(dsaSigner, dig) : new DSADigestSigner(dsaSigner, dig); }
private HMac( Digest digest, int byteLength) { this.digest = digest; digestSize = digest.getDigestSize(); this.blockLength = byteLength; inputPad = new byte[blockLength]; outputPad = new byte[blockLength]; }
public DualECDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; }
protected Signer createSigner(AlgorithmIdentifier sigAlgId) throws OperatorCreationException { AlgorithmIdentifier digAlg = digestAlgorithmFinder.find(sigAlgId); Digest dig = digestProvider.get(digAlg); return new DSADigestSigner(new DSASigner(), dig); }
public RSADigestSigner( Digest digest) { this.digest = digest; algId = new AlgorithmIdentifier((ASN1ObjectIdentifier)oidMap.get(digest.getAlgorithmName()), DERNull.INSTANCE); }
protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId) throws OperatorCreationException { Digest dig = digestProvider.get(digAlgId); return new RSADigestSigner(dig); }
private static void addUserID(Digest digest, byte[] userID) { int len = userID.length * 8; digest.update((byte)(len >> 8 & 0xFF)); digest.update((byte)(len & 0xFF)); digest.update(userID, 0, userID.length); }
/** * Generate a signer for the with either implicit or explicit trailers * for ISO9796-2, scheme 2 or 3. * * @param cipher base cipher to use for signature creation/verification * @param digest digest to use. * @param saltLength length of salt in bytes. * @param implicit whether or not the trailer is implicit or gives the hash. */ public ISO9796d2PSSSigner( AsymmetricBlockCipher cipher, Digest digest, int saltLength, boolean implicit) { this.cipher = cipher; this.digest = digest; this.hLen = digest.getDigestSize(); this.saltLength = saltLength; if (implicit) { trailer = TRAILER_IMPLICIT; } else { Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { trailer = trailerObj.intValue(); } else { throw new IllegalArgumentException("no valid trailer for digest"); } } }
public GenericSigner( AsymmetricBlockCipher engine, Digest digest) { this.engine = engine; this.digest = digest; }
private static String verify() throws Exception { RSAEngine engine = new RSAEngine(); Digest digest = new SHA1Digest(); RSAPublicKey publicKey = (RSAPublicKey) getPublic(publicKeyFilename); BigInteger big = ((RSAKey) publicKey).getModulus(); RSAKeyParameters rsaPublic = new RSAKeyParameters(false, big, publicKey.getPublicExponent()); ISO9796d2Signer verifier = new ISO9796d2Signer(engine, digest, true); verifier.init(false, rsaPublic); // false for verify if (!verifier.verifySignature(signature)) { System.err.println("Signature was modified, could not verify correctness!"); return ""; } String recoveredMessage = ""; try { if (verifier.hasFullMessage()) { verifier.updateWithRecoveredMessage(signature); } byte[] message = verifier.getRecoveredMessage(); recoveredMessage = new String(message, "UTF-8"); } catch (Exception exception) { System.err.println("Recover failed!"); } return recoveredMessage; }
private void putInt(Digest hashAlg, int counter) { hashAlg.update((byte)(counter >> 24)); hashAlg.update((byte)(counter >> 16)); hashAlg.update((byte)(counter >> 8)); hashAlg.update((byte)counter); }
private byte[] calcHash(Digest hashAlg) { byte[] tmp = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(tmp, 0); return tmp; }
/** * Constructor * * @param tailStack a vector element where the stack nodes are stored * @param maxHeight maximal height of the treehash instance * @param digest an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding provider */ public Treehash(Vector tailStack, int maxHeight, Digest digest) { this.tailStack = tailStack; this.maxHeight = maxHeight; this.firstNode = null; this.isInitialized = false; this.isFinished = false; this.seedInitialized = false; this.messDigestTree = digest; this.seedNext = new byte[messDigestTree.getDigestSize()]; this.seedActive = new byte[messDigestTree.getDigestSize()]; }
private static BigInteger calculateGenerator_FIPS186_3_Verifiable(Digest d, BigInteger p, BigInteger q, byte[] seed, int index) { // A.2.3 Verifiable Canonical Generation of the Generator g BigInteger e = p.subtract(ONE).divide(q); byte[] ggen = Hex.decode("6767656E"); // 7. U = domain_parameter_seed || "ggen" || index || count. byte[] U = new byte[seed.length + ggen.length + 1 + 2]; System.arraycopy(seed, 0, U, 0, seed.length); System.arraycopy(ggen, 0, U, seed.length, ggen.length); U[U.length - 3] = (byte)index; byte[] w = new byte[d.getDigestSize()]; for (int count = 1; count < (1 << 16); ++count) { inc(U); hash(d, U, w); BigInteger W = new BigInteger(1, w); BigInteger g = W.modPow(e, p); if (g.compareTo(TWO) >= 0) { return g; } } return null; }
/** * This constructor regenerates a prior GMSSLeaf object * * @param digest an array of strings, containing the name of the used hash * function and PRNG and the name of the corresponding * provider * @param otsIndex status bytes * @param numLeafs status ints */ public GMSSLeaf(Digest digest, byte[][] otsIndex, int[] numLeafs) { this.i = numLeafs[0]; this.j = numLeafs[1]; this.steps = numLeafs[2]; this.w = numLeafs[3]; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private key and the help array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); int checksumsize = getLog((messagesize << w) + 1); this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); this.two_power_w = 1 << w; // calculate steps // ((2^w)-1)*keysize + keysize + 1 / (2^h -1) // initialize arrays this.privateKeyOTS = otsIndex[0]; this.seed = otsIndex[1]; this.concHashs = otsIndex[2]; this.leaf = otsIndex[3]; }
public OAEPEncoding( AsymmetricBlockCipher cipher, Digest hash, byte[] encodingParams) { this(cipher, hash, hash, encodingParams); }
public GMSSLeaf(Digest digest, int w, int numLeafs, byte[] seed0) { this.w = w; messDigestOTS = digest; gmssRandom = new GMSSRandom(messDigestOTS); // calulate keysize for private key and the help array mdsize = messDigestOTS.getDigestSize(); int mdsizeBit = mdsize << 3; int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w); int checksumsize = getLog((messagesize << w) + 1); this.keysize = messagesize + (int)Math.ceil((double)checksumsize / (double)w); this.two_power_w = 1 << w; // calculate steps // ((2^w)-1)*keysize + keysize + 1 / (2^h -1) this.steps = (int)Math .ceil((double)(((1 << w) - 1) * keysize + 1 + keysize) / (double)(numLeafs)); // initialize arrays this.seed = new byte[mdsize]; this.leaf = new byte[mdsize]; this.privateKeyOTS = new byte[mdsize]; this.concHashs = new byte[mdsize * keysize]; initLeafCalc(seed0); }
protected DSABase( Digest digest, DSA signer, DSAEncoder encoder) { this.digest = digest; this.signer = signer; this.encoder = encoder; }
private static ConcurrentBag<ConcurrentBagEntry<Digest>> getMD5MessageDigests() { ConcurrentBag<ConcurrentBagEntry<Digest>> mds = new ConcurrentBag<>(); for (int i = 0; i < PARALLELISM; i++) { Digest md = new SHA1Digest(); mds.add(new ConcurrentBagEntry<>(md)); } return mds; }
public PSSSigner( AsymmetricBlockCipher cipher, Digest contentDigest, Digest mgfDigest, int sLen) { this(cipher, contentDigest, mgfDigest, sLen, TRAILER_IMPLICIT); }
public static PSSSigner createPSSRSASigner(AlgorithmIdentifier sigAlgId, AsymmetricBlockCipher cipher) throws XiSecurityException { ParamUtil.requireNonNull("sigAlgId", sigAlgId); if (!PKCSObjectIdentifiers.id_RSASSA_PSS.equals(sigAlgId.getAlgorithm())) { throw new XiSecurityException("signature algorithm " + sigAlgId.getAlgorithm() + " is not allowed"); } AlgorithmIdentifier digAlgId; try { digAlgId = AlgorithmUtil.extractDigesetAlgFromSigAlg(sigAlgId); } catch (NoSuchAlgorithmException ex) { throw new XiSecurityException(ex.getMessage(), ex); } RSASSAPSSparams param = RSASSAPSSparams.getInstance(sigAlgId.getParameters()); AlgorithmIdentifier mfgDigAlgId = AlgorithmIdentifier.getInstance( param.getMaskGenAlgorithm().getParameters()); Digest dig = getDigest(digAlgId); Digest mfgDig = getDigest(mfgDigAlgId); int saltSize = param.getSaltLength().intValue(); int trailerField = param.getTrailerField().intValue(); AsymmetricBlockCipher tmpCipher = (cipher == null) ? new RSABlindedEngine() : cipher; return new PSSSigner(tmpCipher, dig, mfgDig, saltSize, getTrailer(trailerField)); }
public byte[] generateServerKeyExchange() throws IOException { if (this.dhParameters == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } ByteArrayOutputStream buf = new ByteArrayOutputStream(); DHKeyPairGenerator kpg = new DHKeyPairGenerator(); kpg.init(new DHKeyGenerationParameters(context.getSecureRandom(), this.dhParameters)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); BigInteger Ys = ((DHPublicKeyParameters)kp.getPublic()).getY(); TlsDHUtils.writeDHParameter(dhParameters.getP(), buf); TlsDHUtils.writeDHParameter(dhParameters.getG(), buf); TlsDHUtils.writeDHParameter(Ys, buf); byte[] digestInput = buf.toByteArray(); Digest d = new CombinedHash(); SecurityParameters securityParameters = context.getSecurityParameters(); d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); d.update(digestInput, 0, digestInput.length); byte[] hash = new byte[d.getDigestSize()]; d.doFinal(hash, 0); byte[] sigBytes = serverCredentials.generateCertificateSignature(hash); /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm prepended from TLS 1.2 */ TlsUtils.writeOpaque16(sigBytes, buf); return buf.toByteArray(); }
public static byte[] PRF(TlsContext context, byte[] secret, String asciiLabel, byte[] seed, int size) { ProtocolVersion version = context.getServerVersion(); if (version.isSSL()) { throw new IllegalStateException("No PRF available for SSLv3 session"); } byte[] label = Strings.toByteArray(asciiLabel); byte[] labelSeed = concat(label, seed); int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); if (prfAlgorithm == PRFAlgorithm.tls_prf_legacy) { if (!ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(version.getEquivalentTLSVersion())) { return PRF_legacy(secret, label, labelSeed, size); } prfAlgorithm = PRFAlgorithm.tls_prf_sha256; } Digest prfDigest = createPRFHash(prfAlgorithm); byte[] buf = new byte[size]; hmac_hash(prfDigest, secret, labelSeed, buf); return buf; }
public DigestRandomGenerator( Digest digest) { this.digest = digest; this.seed = new byte[digest.getDigestSize()]; this.seedCounter = 1; this.state = new byte[digest.getDigestSize()]; this.stateCounter = 1; }
static byte[] calculateKeyBlock_SSL(byte[] master_secret, byte[] random, int size) { Digest md5 = new MD5Digest(); Digest sha1 = new SHA1Digest(); int md5Size = md5.getDigestSize(); byte[] shatmp = new byte[sha1.getDigestSize()]; byte[] tmp = new byte[size + md5Size]; int i = 0, pos = 0; while (pos < size) { byte[] ssl3Const = SSL3_CONST[i]; sha1.update(ssl3Const, 0, ssl3Const.length); sha1.update(master_secret, 0, master_secret.length); sha1.update(random, 0, random.length); sha1.doFinal(shatmp, 0); md5.update(master_secret, 0, master_secret.length); md5.update(shatmp, 0, shatmp.length); md5.doFinal(tmp, pos); pos += md5Size; ++i; } byte rval[] = new byte[size]; System.arraycopy(tmp, 0, rval, 0, size); return rval; }