public static PrivateKeyInfo CreatePrivateKeyInfo( AsymmetricKeyParameter key) { if (key == null) { throw new ArgumentNullException("key"); } if (!key.IsPrivate) { throw new ArgumentException("Public key passed - private key expected", "key"); } if (key is ElGamalPrivateKeyParameters) { ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key; return(new PrivateKeyInfo( new AlgorithmIdentifier( OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter( _key.Parameters.P, _key.Parameters.G).ToAsn1Object()), new DerInteger(_key.X))); } if (key is DsaPrivateKeyParameters) { DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)key; return(new PrivateKeyInfo( new AlgorithmIdentifier( X9ObjectIdentifiers.IdDsa, new DsaParameter( _key.Parameters.P, _key.Parameters.Q, _key.Parameters.G).ToAsn1Object()), new DerInteger(_key.X))); } if (key is DHPrivateKeyParameters) { DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key; DHParameter p = new DHParameter( _key.Parameters.P, _key.Parameters.G, _key.Parameters.L); return(new PrivateKeyInfo( new AlgorithmIdentifier(_key.AlgorithmOid, p.ToAsn1Object()), new DerInteger(_key.X))); } if (key is RsaKeyParameters) { AlgorithmIdentifier algID = new AlgorithmIdentifier( PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); RsaPrivateKeyStructure keyStruct; if (key is RsaPrivateCrtKeyParameters) { RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)key; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, _key.PublicExponent, _key.Exponent, _key.P, _key.Q, _key.DP, _key.DQ, _key.QInv); } else { RsaKeyParameters _key = (RsaKeyParameters)key; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, BigInteger.Zero, _key.Exponent, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero); } return(new PrivateKeyInfo(algID, keyStruct.ToAsn1Object())); } if (key is ECPrivateKeyParameters) { ECPrivateKeyParameters priv = (ECPrivateKeyParameters)key; ECDomainParameters dp = priv.Parameters; int orderBitLength = dp.N.BitLength; AlgorithmIdentifier algID; ECPrivateKeyStructure ec; if (priv.AlgorithmName == "ECGOST3410") { if (priv.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( priv.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gostParams); // TODO Do we need to pass any parameters here? ec = new ECPrivateKeyStructure(orderBitLength, priv.D); } else { X962Parameters x962; if (priv.PublicKeyParamSet == null) { X9ECParameters ecP = new X9ECParameters(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()); x962 = new X962Parameters(ecP); } else { x962 = new X962Parameters(priv.PublicKeyParamSet); } // TODO Possible to pass the publicKey bitstring here? ec = new ECPrivateKeyStructure(orderBitLength, priv.D, x962); algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962); } return(new PrivateKeyInfo(algID, ec)); } if (key is Gost3410PrivateKeyParameters) { Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)key; if (_key.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } byte[] keyEnc = _key.X.ToByteArrayUnsigned(); byte[] keyBytes = new byte[keyEnc.Length]; for (int i = 0; i != keyBytes.Length; i++) { keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian } Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); AlgorithmIdentifier algID = new AlgorithmIdentifier( CryptoProObjectIdentifiers.GostR3410x94, algParams.ToAsn1Object()); return(new PrivateKeyInfo(algID, new DerOctetString(keyBytes))); } throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(key)); }
internal PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSha1, SecureRandom rand, bool isMasterKey) { BcpgObject secKey; this.pub = pubKey; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters)privKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters)privKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; default: throw new PgpException("unknown key class"); } try { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); pOut.WriteObject(secKey); byte[] keyData = bOut.ToArray(); byte[] checksumBytes = Checksum(useSha1, keyData, keyData.Length); pOut.Write(checksumBytes); byte[] bOutData = bOut.ToArray(); if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) { if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData); } } else { S2k s2k; byte[] iv; byte[] encData = EncryptKeyData(bOutData, encAlgorithm, passPhrase, rand, out s2k, out iv); int s2kUsage = useSha1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } } } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } }
/// <summary>Extract a <c>PgpPrivateKey</c> from this secret key's encrypted contents.</summary> public PgpPrivateKey ExtractPrivateKey( char[] passPhrase) { byte[] secKeyData = secret.GetSecretKeyData(); if (secKeyData == null || secKeyData.Length < 1) { return(null); } PublicKeyPacket pubPk = secret.PublicKeyPacket; try { byte[] data = ExtractKeyData(passPhrase); BcpgInputStream bcpgIn = BcpgInputStream.Wrap(new MemoryStream(data, false)); AsymmetricKeyParameter privateKey; switch (pubPk.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaSign: RsaPublicBcpgKey rsaPub = (RsaPublicBcpgKey)pubPk.Key; RsaSecretBcpgKey rsaPriv = new RsaSecretBcpgKey(bcpgIn); RsaPrivateCrtKeyParameters rsaPrivSpec = new RsaPrivateCrtKeyParameters( rsaPriv.Modulus, rsaPub.PublicExponent, rsaPriv.PrivateExponent, rsaPriv.PrimeP, rsaPriv.PrimeQ, rsaPriv.PrimeExponentP, rsaPriv.PrimeExponentQ, rsaPriv.CrtCoefficient); privateKey = rsaPrivSpec; break; case PublicKeyAlgorithmTag.Dsa: DsaPublicBcpgKey dsaPub = (DsaPublicBcpgKey)pubPk.Key; DsaSecretBcpgKey dsaPriv = new DsaSecretBcpgKey(bcpgIn); DsaParameters dsaParams = new DsaParameters(dsaPub.P, dsaPub.Q, dsaPub.G); privateKey = new DsaPrivateKeyParameters(dsaPriv.X, dsaParams); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPublicBcpgKey elPub = (ElGamalPublicBcpgKey)pubPk.Key; ElGamalSecretBcpgKey elPriv = new ElGamalSecretBcpgKey(bcpgIn); ElGamalParameters elParams = new ElGamalParameters(elPub.P, elPub.G); privateKey = new ElGamalPrivateKeyParameters(elPriv.X, elParams); break; default: throw new PgpException("unknown public key algorithm encountered"); } return(new PgpPrivateKey(privateKey, KeyId)); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception constructing key", e); } }
public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter key) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) if (key == null) { throw new ArgumentNullException("key"); } if (!key.IsPrivate) { throw new ArgumentException("Public key passed - private key expected", "key"); } if (key is ElGamalPrivateKeyParameters) { ElGamalPrivateKeyParameters elGamalPrivateKeyParameters = (ElGamalPrivateKeyParameters)key; return(new PrivateKeyInfo(new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(elGamalPrivateKeyParameters.Parameters.P, elGamalPrivateKeyParameters.Parameters.G).ToAsn1Object()), new DerInteger(elGamalPrivateKeyParameters.X))); } if (key is DsaPrivateKeyParameters) { DsaPrivateKeyParameters dsaPrivateKeyParameters = (DsaPrivateKeyParameters)key; return(new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, new DsaParameter(dsaPrivateKeyParameters.Parameters.P, dsaPrivateKeyParameters.Parameters.Q, dsaPrivateKeyParameters.Parameters.G).ToAsn1Object()), new DerInteger(dsaPrivateKeyParameters.X))); } if (key is DHPrivateKeyParameters) { DHPrivateKeyParameters dHPrivateKeyParameters = (DHPrivateKeyParameters)key; DHParameter dHParameter = new DHParameter(dHPrivateKeyParameters.Parameters.P, dHPrivateKeyParameters.Parameters.G, dHPrivateKeyParameters.Parameters.L); return(new PrivateKeyInfo(new AlgorithmIdentifier(dHPrivateKeyParameters.AlgorithmOid, dHParameter.ToAsn1Object()), new DerInteger(dHPrivateKeyParameters.X))); } if (key is RsaKeyParameters) { AlgorithmIdentifier algID = new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); RsaPrivateKeyStructure rsaPrivateKeyStructure; if (key is RsaPrivateCrtKeyParameters) { RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)key; rsaPrivateKeyStructure = new RsaPrivateKeyStructure(rsaPrivateCrtKeyParameters.Modulus, rsaPrivateCrtKeyParameters.PublicExponent, rsaPrivateCrtKeyParameters.Exponent, rsaPrivateCrtKeyParameters.P, rsaPrivateCrtKeyParameters.Q, rsaPrivateCrtKeyParameters.DP, rsaPrivateCrtKeyParameters.DQ, rsaPrivateCrtKeyParameters.QInv); } else { RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)key; rsaPrivateKeyStructure = new RsaPrivateKeyStructure(rsaKeyParameters.Modulus, BigInteger.Zero, rsaKeyParameters.Exponent, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero); } return(new PrivateKeyInfo(algID, rsaPrivateKeyStructure.ToAsn1Object())); } if (key is ECPrivateKeyParameters) { ECPrivateKeyParameters eCPrivateKeyParameters = (ECPrivateKeyParameters)key; ECDomainParameters parameters = eCPrivateKeyParameters.Parameters; int bitLength = parameters.N.BitLength; AlgorithmIdentifier algID2; ECPrivateKeyStructure privateKey; if (eCPrivateKeyParameters.AlgorithmName == "ECGOST3410") { if (eCPrivateKeyParameters.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } Gost3410PublicKeyAlgParameters parameters2 = new Gost3410PublicKeyAlgParameters(eCPrivateKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); algID2 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, parameters2); privateKey = new ECPrivateKeyStructure(bitLength, eCPrivateKeyParameters.D); } else { X962Parameters parameters3; if (eCPrivateKeyParameters.PublicKeyParamSet == null) { X9ECParameters ecParameters = new X9ECParameters(parameters.Curve, parameters.G, parameters.N, parameters.H, parameters.GetSeed()); parameters3 = new X962Parameters(ecParameters); } else { parameters3 = new X962Parameters(eCPrivateKeyParameters.PublicKeyParamSet); } privateKey = new ECPrivateKeyStructure(bitLength, eCPrivateKeyParameters.D, parameters3); algID2 = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, parameters3); } return(new PrivateKeyInfo(algID2, privateKey)); } if (key is Gost3410PrivateKeyParameters) { Gost3410PrivateKeyParameters gost3410PrivateKeyParameters = (Gost3410PrivateKeyParameters)key; if (gost3410PrivateKeyParameters.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } byte[] array = gost3410PrivateKeyParameters.X.ToByteArrayUnsigned(); byte[] array2 = new byte[array.Length]; for (int i = 0; i != array2.Length; i++) { array2[i] = array[array.Length - 1 - i]; } Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters(gost3410PrivateKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); AlgorithmIdentifier algID3 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x94, gost3410PublicKeyAlgParameters.ToAsn1Object()); return(new PrivateKeyInfo(algID3, new DerOctetString(array2))); } throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(key)); }
/// <summary>Return the decrypted data stream for the packet.</summary> public Stream GetDataStream( PgpPrivateKey privKey) { IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm); try { c1.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } BigInteger[] keyD = keyData.GetEncSessionKey(); if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral) { byte[] bi = keyD[0].ToByteArray(); if (bi[0] == 0) { c1.ProcessBytes(bi, 1, bi.Length - 1); } else { c1.ProcessBytes(bi, 0, bi.Length); } } else { ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key; int size = (k.Parameters.P.BitLength + 7) / 8; byte[] bi = keyD[0].ToByteArray(); int diff = bi.Length - size; if (diff >= 0) { c1.ProcessBytes(bi, diff, size); } else { byte[] zeros = new byte[-diff]; c1.ProcessBytes(zeros); c1.ProcessBytes(bi); } bi = keyD[1].ToByteArray(); diff = bi.Length - size; if (diff >= 0) { c1.ProcessBytes(bi, diff, size); } else { byte[] zeros = new byte[-diff]; c1.ProcessBytes(zeros); c1.ProcessBytes(bi); } } byte[] plain; try { plain = c1.DoFinal(); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } if (!ConfirmCheckSum(plain)) { throw new PgpKeyValidationException("key checksum failed"); } IBufferedCipher c2; string cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]); string cName = cipherName; try { if (encData is SymmetricEncIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c2 = CipherUtilities.GetCipher(cName); } // catch (NoSuchProviderException e) catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("exception creating cipher", e); } if (c2 == null) { return(encData.GetInputStream()); } try { byte[] keyBytes = new byte[plain.Length - 3]; Array.Copy(plain, 1, keyBytes, 0, keyBytes.Length); KeyParameter key = ParameterUtilities.CreateKeyParameter( cipherName, keyBytes); byte[] iv = new byte[c2.GetBlockSize()]; c2.Init(false, new ParametersWithIV(key, iv)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); encStream = new DigestStream(truncStream, DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)), null); } for (int i = 0; i != iv.Length; i++) { int ch = encStream.ReadByte(); if (ch < 0) { throw new EndOfStreamException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.ReadByte(); int v2 = encStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is deemed // a security risk for typical public key encryption usages, // therefore we do not perform the check. // bool repeatCheckPassed = // iv[iv.Length - 2] == (byte)v1 // && iv[iv.Length - 1] == (byte)v2; // // // Note: some versions of PGP appear to produce 0 for the extra // // bytes rather than repeating the two previous bytes // bool zeroesCheckPassed = // v1 == 0 // && v2 == 0; // // if (!repeatCheckPassed && !zeroesCheckPassed) // { // throw new PgpDataValidationException("quick check failed."); // } return(encStream); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception starting decryption", e); } }
/** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param length the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public virtual byte[] ProcessBlock( byte[] input, int inOff, int length) { if (key == null) { throw new InvalidOperationException("ElGamal engine not initialised"); } int maxLength = forEncryption ? (bitSize - 1 + 7) / 8 : GetInputBlockSize(); if (length > maxLength) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } BigInteger p = key.Parameters.P; byte[] output; if (key is ElGamalPrivateKeyParameters) // decryption { int halfLength = length / 2; BigInteger gamma = new BigInteger(1, input, inOff, halfLength); BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key; // a shortcut, which generally relies on p being prime amongst other things. // if a problem with this shows up, check the p and g values! BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); output = m.ToByteArrayUnsigned(); } else // encryption { BigInteger tmp = new BigInteger(1, input, inOff, length); if (tmp.BitLength >= p.BitLength) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key; BigInteger pSub2 = p.Subtract(BigInteger.Two); // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated BigInteger k; do { k = new BigInteger(p.BitLength, random); }while (k.SignValue == 0 || k.CompareTo(pSub2) > 0); BigInteger g = key.Parameters.G; BigInteger gamma = g.ModPow(k, p); BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p); output = new byte[this.GetOutputBlockSize()]; // TODO Add methods to allow writing BigInteger to existing byte array? byte[] out1 = gamma.ToByteArrayUnsigned(); byte[] out2 = phi.ToByteArrayUnsigned(); out1.CopyTo(output, output.Length / 2 - out1.Length); out2.CopyTo(output, output.Length - out2.Length); } return(output); }
private byte[] RecoverSessionData(PgpPrivateKey privKey) { byte[][] secKeyData = keyData.GetEncSessionKey(); if (keyData.Algorithm == PublicKeyAlgorithmTag.ECDH) { ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)privKey.PublicKeyPacket.Key; X9ECParameters x9Params = ECKeyPairGenerator.FindECCurveByOid(ecKey.CurveOid); byte[] enc = secKeyData[0]; int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; byte[] pEnc = new byte[pLen]; Array.Copy(enc, 2, pEnc, 0, pLen); byte[] keyEnc = new byte[enc[pLen + 2]]; Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length); ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc); ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key; ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize(); KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S)); IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); w.Init(false, key); return(PgpPad.UnpadSessionData(w.Unwrap(keyEnc, 0, keyEnc.Length))); } IBufferedCipher cipher = GetKeyCipher(keyData.Algorithm); try { cipher.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral) { byte[] bi = secKeyData[0]; cipher.ProcessBytes(bi, 2, bi.Length - 2); } else { ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key; int size = (k.Parameters.P.BitLength + 7) / 8; ProcessEncodedMpi(cipher, size, secKeyData[0]); ProcessEncodedMpi(cipher, size, secKeyData[1]); } try { return(cipher.DoFinal()); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } }
public static PrivateKeyInfo CreatePrivateKeyInfo( AsymmetricKeyParameter key) { if (key == null) { throw new ArgumentNullException("key"); } if (!key.IsPrivate) { throw new ArgumentException("Public key passed - private key expected", "key"); } if (key is ElGamalPrivateKeyParameters) { ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key; return(new PrivateKeyInfo( new AlgorithmIdentifier( OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter( _key.Parameters.P, _key.Parameters.G).ToAsn1Object()), new DerInteger(_key.X))); } if (key is DsaPrivateKeyParameters) { DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)key; return(new PrivateKeyInfo( new AlgorithmIdentifier( X9ObjectIdentifiers.IdDsa, new DsaParameter( _key.Parameters.P, _key.Parameters.Q, _key.Parameters.G).ToAsn1Object()), new DerInteger(_key.X))); } if (key is DHPrivateKeyParameters) { /* * Process DH private key. * The value for L was set to zero implicitly. * This is the same action as found in JCEDHPrivateKey GetEncoded method. */ DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key; DHParameter withNewL = new DHParameter( _key.Parameters.P, _key.Parameters.G, 0); return(new PrivateKeyInfo( new AlgorithmIdentifier( PkcsObjectIdentifiers.DhKeyAgreement, withNewL.ToAsn1Object()), new DerInteger(_key.X))); } if (key is RsaKeyParameters) { AlgorithmIdentifier algID = new AlgorithmIdentifier( PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); RsaPrivateKeyStructure keyStruct; if (key is RsaPrivateCrtKeyParameters) { RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)key; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, _key.PublicExponent, _key.Exponent, _key.P, _key.Q, _key.DP, _key.DQ, _key.QInv); } else { RsaKeyParameters _key = (RsaKeyParameters)key; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, BigInteger.Zero, _key.Exponent, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero); } return(new PrivateKeyInfo(algID, keyStruct.ToAsn1Object())); } if (key is ECPrivateKeyParameters) { ECPrivateKeyParameters _key = (ECPrivateKeyParameters)key; AlgorithmIdentifier algID; if (_key.AlgorithmName == "ECGOST3410") { if (_key.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); algID = new AlgorithmIdentifier( CryptoProObjectIdentifiers.GostR3410x2001, gostParams.ToAsn1Object()); } else { X9ECParameters ecP = new X9ECParameters( _key.Parameters.Curve, _key.Parameters.G, _key.Parameters.N, _key.Parameters.H, _key.Parameters.GetSeed()); X962Parameters x962 = new X962Parameters(ecP); algID = new AlgorithmIdentifier( X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object()); } return(new PrivateKeyInfo(algID, new ECPrivateKeyStructure(_key.D).ToAsn1Object())); } if (key is Gost3410PrivateKeyParameters) { Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)key; if (_key.PublicKeyParamSet == null) { throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } byte[] keyEnc = _key.X.ToByteArrayUnsigned(); byte[] keyBytes = new byte[keyEnc.Length]; for (int i = 0; i != keyBytes.Length; i++) { keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian } Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); AlgorithmIdentifier algID = new AlgorithmIdentifier( CryptoProObjectIdentifiers.GostR3410x94, algParams.ToAsn1Object()); return(new PrivateKeyInfo(algID, new DerOctetString(keyBytes))); } throw new ArgumentException("Class provided is not convertible: " + key.GetType().FullName); }
/** * Create a PrivateKeyInfo representation of a private key with attributes. * * @param privateKey the key to be encoded into the info object. * @param attributes the set of attributes to be included. * @return the appropriate PrivateKeyInfo * @throws java.io.IOException on an error encoding the key */ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey, Asn1Set attributes) { if (privateKey == null) { throw new ArgumentNullException("privateKey"); } if (!privateKey.IsPrivate) { throw new ArgumentException("Public key passed - private key expected", "privateKey"); } if (privateKey is ElGamalPrivateKeyParameters) { ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)privateKey; ElGamalParameters egp = _key.Parameters; return(new PrivateKeyInfo( new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(egp.P, egp.G).ToAsn1Object()), new DerInteger(_key.X), attributes)); } if (privateKey is DsaPrivateKeyParameters) { DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)privateKey; DsaParameters dp = _key.Parameters; return(new PrivateKeyInfo( new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, new DsaParameter(dp.P, dp.Q, dp.G).ToAsn1Object()), new DerInteger(_key.X), attributes)); } if (privateKey is DHPrivateKeyParameters) { DHPrivateKeyParameters _key = (DHPrivateKeyParameters)privateKey; DHParameter p = new DHParameter( _key.Parameters.P, _key.Parameters.G, _key.Parameters.L); return(new PrivateKeyInfo( new AlgorithmIdentifier(_key.AlgorithmOid, p.ToAsn1Object()), new DerInteger(_key.X), attributes)); } if (privateKey is RsaKeyParameters) { AlgorithmIdentifier algID = new AlgorithmIdentifier( PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); RsaPrivateKeyStructure keyStruct; if (privateKey is RsaPrivateCrtKeyParameters) { RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)privateKey; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, _key.PublicExponent, _key.Exponent, _key.P, _key.Q, _key.DP, _key.DQ, _key.QInv); } else { RsaKeyParameters _key = (RsaKeyParameters)privateKey; keyStruct = new RsaPrivateKeyStructure( _key.Modulus, BigInteger.Zero, _key.Exponent, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero); } return(new PrivateKeyInfo(algID, keyStruct.ToAsn1Object(), attributes)); } if (privateKey is ECPrivateKeyParameters) { ECPrivateKeyParameters priv = (ECPrivateKeyParameters)privateKey; DerBitString publicKey = new DerBitString(ECKeyPairGenerator.GetCorrespondingPublicKey(priv).Q.GetEncoded(false)); ECDomainParameters dp = priv.Parameters; // ECGOST3410 if (dp is ECGost3410Parameters) { ECGost3410Parameters domainParameters = (ECGost3410Parameters)dp; Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( (domainParameters).PublicKeyParamSet, (domainParameters).DigestParamSet, (domainParameters).EncryptionParamSet); bool is512 = priv.D.BitLength > 256; DerObjectIdentifier identifier = (is512) ? RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; int size = (is512) ? 64 : 32; byte[] encKey = new byte[size]; ExtractBytes(encKey, size, 0, priv.D); return(new PrivateKeyInfo(new AlgorithmIdentifier(identifier, gostParams), new DerOctetString(encKey))); } int orderBitLength = dp.N.BitLength; AlgorithmIdentifier algID; ECPrivateKeyStructure ec; if (priv.AlgorithmName == "ECGOST3410") { if (priv.PublicKeyParamSet == null) { throw BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( priv.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gostParams); // TODO Do we need to pass any parameters here? ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, null); } else { X962Parameters x962; if (priv.PublicKeyParamSet == null) { X9ECParameters ecP = new X9ECParameters(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()); x962 = new X962Parameters(ecP); } else { x962 = new X962Parameters(priv.PublicKeyParamSet); } ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, x962); algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962); } return(new PrivateKeyInfo(algID, ec, attributes)); } if (privateKey is Gost3410PrivateKeyParameters) { Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)privateKey; if (_key.PublicKeyParamSet == null) { throw BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); } byte[] keyEnc = _key.X.ToByteArrayUnsigned(); byte[] keyBytes = new byte[keyEnc.Length]; for (int i = 0; i != keyBytes.Length; i++) { keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian } Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); AlgorithmIdentifier algID = new AlgorithmIdentifier( CryptoProObjectIdentifiers.GostR3410x94, algParams.ToAsn1Object()); return(new PrivateKeyInfo(algID, new DerOctetString(keyBytes), attributes)); } if (privateKey is X448PrivateKeyParameters) { X448PrivateKeyParameters key = (X448PrivateKeyParameters)privateKey; return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded())); } if (privateKey is X25519PrivateKeyParameters) { X25519PrivateKeyParameters key = (X25519PrivateKeyParameters)privateKey; return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded())); } if (privateKey is Ed448PrivateKeyParameters) { Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters)privateKey; return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded())); } if (privateKey is Ed25519PrivateKeyParameters) { Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters)privateKey; return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded())); } throw new ArgumentException("Class provided is not convertible: " + BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.GetTypeName(privateKey)); }
internal PgpSecretKey( PgpKeyPair keyPair, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSHA1, SecureRandom rand) { PublicKeyPacket pubPk = keyPair.PublicKey.publicPk; BcpgObject secKey; switch (keyPair.PublicKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters)keyPair.PrivateKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters)keyPair.PrivateKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)keyPair.PrivateKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; default: throw new PgpException("unknown key class"); } string cName = PgpUtilities.GetSymmetricCipherName(encAlgorithm); IBufferedCipher c = null; if (cName != null) { try { c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } } try { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); pOut.WriteObject(secKey); byte[] keyData = bOut.ToArray(); byte[] checksumBytes = Checksum(useSHA1, keyData, keyData.Length); pOut.Write(checksumBytes); byte[] bOutData = bOut.ToArray(); if (c != null) { byte[] iv = new byte[8]; rand.NextBytes(iv); S2k s2k = new S2k(HashAlgorithmTag.Sha1, iv, 0x60); KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(encAlgorithm, s2k, passPhrase); iv = new byte[c.GetBlockSize()]; rand.NextBytes(iv); c.Init(true, new ParametersWithIV(key, iv)); byte[] encData = c.DoFinal(bOutData); int usage = useSHA1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; this.secret = new SecretKeyPacket(pubPk, encAlgorithm, usage, s2k, iv, encData); } else { this.secret = new SecretKeyPacket(pubPk, encAlgorithm, null, null, bOutData); } this.trust = null; } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } this.keySigs = new ArrayList(); }
private void DoTestGp( int size, int privateValueSize, IBigInteger g, IBigInteger p) { IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ElGamal"); // DHParameterSpec elParams = new DHParameterSpec(p, g); // keyGen.initialize(elParams); ElGamalParameters elParams = new ElGamalParameters(p, g, privateValueSize); ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters( new SecureRandom(), elParams); keyGen.Init(elKgp); IAsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair(); SecureRandom rand = new SecureRandom(); checkKeySize(privateValueSize, keyPair); IBufferedCipher cipher = CipherUtilities.GetCipher("ElGamal"); cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand)); byte[] inBytes = Encoding.ASCII.GetBytes("This is a test"); if (cipher.GetOutputSize(inBytes.Length) != (size / 8) * 2) { Fail("getOutputSize wrong on encryption"); } byte[] outBytes = cipher.DoFinal(inBytes); cipher.Init(false, keyPair.Private); if (cipher.GetOutputSize(outBytes.Length) != (size / 8) - 1) { Fail("GetOutputSize wrong on decryption"); } // // No Padding - maximum length // byte[] modBytes = ((ElGamalPublicKeyParameters)keyPair.Public).Parameters.P.ToByteArray(); byte[] maxInput = new byte[modBytes.Length - 1]; maxInput[0] |= 0x7f; cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand)); outBytes = cipher.DoFinal(maxInput); cipher.Init(false, keyPair.Private); outBytes = cipher.DoFinal(outBytes); if (!AreEqual(outBytes, maxInput)) { Fail("NoPadding test failed on decrypt expected " + Hex.ToHexString(maxInput) + " got " + Hex.ToHexString(outBytes)); } // // encrypt/decrypt // IBufferedCipher c1 = CipherUtilities.GetCipher("ElGamal"); IBufferedCipher c2 = CipherUtilities.GetCipher("ElGamal"); c1.Init(true, new ParametersWithRandom(keyPair.Public, rand)); byte[] out1 = c1.DoFinal(inBytes); c2.Init(false, keyPair.Private); byte[] out2 = c2.DoFinal(out1); if (!AreEqual(inBytes, out2)) { Fail(size + " encrypt test failed"); } // // encrypt/decrypt with update // int outLen = c1.ProcessBytes(inBytes, 0, 2, out1, 0); outLen += c1.DoFinal(inBytes, 2, inBytes.Length - 2, out1, outLen); outLen = c2.ProcessBytes(out1, 0, 2, out2, 0); outLen += c2.DoFinal(out1, 2, out1.Length - 2, out2, outLen); if (!AreEqual(inBytes, out2)) { Fail(size + " encrypt with update test failed"); } // // public key encoding test // // byte[] pubEnc = keyPair.Public.GetEncoded(); byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public).GetDerEncoded(); // KeyFactory keyFac = KeyFactory.GetInstance("ElGamal"); // X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); // DHPublicKeyParameters pubKey = (DHPublicKeyParameters)keyFac.generatePublic(pubX509); ElGamalPublicKeyParameters pubKey = (ElGamalPublicKeyParameters) PublicKeyFactory.CreateKey(pubEnc); ElGamalParameters spec = pubKey.Parameters; if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P)) { Fail(size + " bit public key encoding/decoding test failed on parameters"); } if (!((ElGamalPublicKeyParameters)keyPair.Public).Y.Equals(pubKey.Y)) { Fail(size + " bit public key encoding/decoding test failed on y value"); } /* * // * // public key serialisation test * // * // TODO Is there some standard this serialization must conform to? * BinaryFormatter formatter = new BinaryFormatter(); * * MemoryStream bOut = new MemoryStream(); * // ObjectOutputStream oOut = new ObjectOutputStream(bOut); * // oOut.writeObject(keyPair.Public); * formatter.Serialize(bOut, keyPair.Public); * * MemoryStream bIn = new MemoryStream(bOut.ToArray(), false); * // ObjectInputStream oIn = new ObjectInputStream(bIn); * // pubKey = (DHPublicKeyParameters)oIn.readObject(); * pubKey = (ElGamalPublicKeyParameters) formatter.Deserialize(bIn); * spec = pubKey.Parameters; * * if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P)) * { * Fail(size + " bit public key serialisation test failed on parameters"); * } * * if (!((ElGamalPublicKeyParameters )keyPair.Public).Y.Equals(pubKey.Y)) * { * Fail(size + " bit public key serialisation test failed on y value"); * } */ // // private key encoding test // // TODO Keys don't support GetEncoded // byte[] privEnc = keyPair.Private.GetEncoded(); byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private).GetDerEncoded(); // PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); // DHPrivateKeyParameters privKey = (DHPrivateKeyParameters)keyFac.generatePrivate(privPKCS8); ElGamalPrivateKeyParameters privKey = (ElGamalPrivateKeyParameters) PrivateKeyFactory.CreateKey(privEnc); spec = privKey.Parameters; if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P)) { Fail(size + " bit private key encoding/decoding test failed on parameters"); } if (!((ElGamalPrivateKeyParameters)keyPair.Private).X.Equals(privKey.X)) { Fail(size + " bit private key encoding/decoding test failed on y value"); } /* * // * // private key serialisation test * // * bOut = new MemoryStream(); * // oOut = new ObjectOutputStream(bOut); * // oOut.writeObject(keyPair.Private); * formatter.Serialize(bOut, keyPair.Private); * * bIn = new MemoryStream(bOut.ToArray(), false); * // oIn = new ObjectInputStream(bIn); * // privKey = (DHPrivateKeyParameters)oIn.readObject(); * privKey = (ElGamalPrivateKeyParameters) formatter.Deserialize(bIn); * spec = privKey.Parameters; * * if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P)) * { * Fail(size + " bit private key serialisation test failed on parameters"); * } * * if (!((ElGamalPrivateKeyParameters) keyPair.Private).X.Equals(privKey.X)) * { * Fail(size + " bit private key serialisation test failed on y value"); * } */ }
private byte[] fetchSymmetricKeyData( PgpPrivateKey privKey) { IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm); try { c1.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } BigInteger[] keyD = keyData.GetEncSessionKey(); if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral) { c1.ProcessBytes(keyD[0].ToByteArrayUnsigned()); } else { ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key; int size = (k.Parameters.P.BitLength + 7) / 8; byte[] bi = keyD[0].ToByteArray(); int diff = bi.Length - size; if (diff >= 0) { c1.ProcessBytes(bi, diff, size); } else { byte[] zeros = new byte[-diff]; c1.ProcessBytes(zeros); c1.ProcessBytes(bi); } bi = keyD[1].ToByteArray(); diff = bi.Length - size; if (diff >= 0) { c1.ProcessBytes(bi, diff, size); } else { byte[] zeros = new byte[-diff]; c1.ProcessBytes(zeros); c1.ProcessBytes(bi); } } byte[] plain; try { plain = c1.DoFinal(); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } if (!ConfirmCheckSum(plain)) { throw new PgpKeyValidationException("key checksum failed"); } return(plain); }
/** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public byte[] processBlock( byte[] inBytes, int inOff, int inLen) { if (inLen > (getInputBlockSize() + 1)) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } else if (inLen == (getInputBlockSize() + 1) && (inBytes[inOff] & 0x80) != 0) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } byte[] block; if (inOff != 0 || inLen != inBytes.Length) { block = new byte[inLen]; Array.Copy(inBytes, inOff, block, 0, inLen); } else { block = inBytes; } BigInteger input = new BigInteger(1, block); BigInteger g = key.getParameters().getG(); BigInteger p = key.getParameters().getP(); if (typeof(ElGamalPrivateKeyParameters).IsInstanceOfType(key)) { byte[] in1 = new byte[inBytes.Length / 2]; byte[] in2 = new byte[inBytes.Length / 2]; Array.Copy(inBytes, 0, in1, 0, in1.Length); Array.Copy(inBytes, in1.Length, in2, 0, in2.Length); BigInteger gamma = new BigInteger(1, in1); BigInteger phi = new BigInteger(1, in2); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key; BigInteger m = gamma.modPow(p.subtract(ONE).subtract(priv.getX()), p).multiply(phi).mod(p); byte[] outBytes = m.toByteArray(); if (outBytes[0] != 0) { return(outBytes); } else { byte[] output = new byte[outBytes.Length - 1]; Array.Copy(outBytes, 1, output, 0, output.Length); return(output); } } else { ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key; BigInteger k = new BigInteger(p.bitLength(), random); while (k.Equals(ZERO) || (k.compareTo(p.subtract(TWO)) > 0)) { k = new BigInteger(p.bitLength(), random); } BigInteger gamma = g.modPow(k, p); BigInteger phi = input.multiply(pub.getY().modPow(k, p)).mod(p); byte[] out1 = gamma.toByteArray(); byte[] out2 = phi.toByteArray(); byte[] output = new byte[this.getOutputBlockSize()]; if (out1[0] == 0) { Array.Copy(out1, 1, output, output.Length / 2 - (out1.Length - 1), out1.Length - 1); } else { Array.Copy(out1, 0, output, output.Length / 2 - out1.Length, out1.Length); } if (out2[0] == 0) { Array.Copy(out2, 1, output, output.Length - (out2.Length - 1), out2.Length - 1); } else { Array.Copy(out2, 0, output, output.Length - out2.Length, out2.Length); } return(output); } }
internal PgpSecretKey(PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, byte[] rawPassPhrase, bool clearPassPhrase, bool useSha1, SecureRandom rand, bool isMasterKey) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown pub = pubKey; BcpgObject bcpgObject; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: { RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)privKey.Key; bcpgObject = new RsaSecretBcpgKey(rsaPrivateCrtKeyParameters.Exponent, rsaPrivateCrtKeyParameters.P, rsaPrivateCrtKeyParameters.Q); break; } case PublicKeyAlgorithmTag.Dsa: { DsaPrivateKeyParameters dsaPrivateKeyParameters = (DsaPrivateKeyParameters)privKey.Key; bcpgObject = new DsaSecretBcpgKey(dsaPrivateKeyParameters.X); break; } case PublicKeyAlgorithmTag.EC: case PublicKeyAlgorithmTag.ECDsa: { ECPrivateKeyParameters eCPrivateKeyParameters = (ECPrivateKeyParameters)privKey.Key; bcpgObject = new ECSecretBcpgKey(eCPrivateKeyParameters.D); break; } case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: { ElGamalPrivateKeyParameters elGamalPrivateKeyParameters = (ElGamalPrivateKeyParameters)privKey.Key; bcpgObject = new ElGamalSecretBcpgKey(elGamalPrivateKeyParameters.X); break; } default: throw new PgpException("unknown key class"); } try { MemoryStream val = new MemoryStream(); BcpgOutputStream bcpgOutputStream = new BcpgOutputStream((Stream)(object)val); bcpgOutputStream.WriteObject(bcpgObject); byte[] array = val.ToArray(); byte[] b = Checksum(useSha1, array, array.Length); array = Arrays.Concatenate(array, b); if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) { if (isMasterKey) { secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, array); } else { secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, array); } return; } S2k s2k; byte[] iv; byte[] secKeyData = ((pub.Version < 4) ? EncryptKeyDataV3(array, encAlgorithm, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv) : EncryptKeyDataV4(array, encAlgorithm, HashAlgorithmTag.Sha1, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv)); int s2kUsage = (useSha1 ? 254 : 255); if (isMasterKey) { secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, secKeyData); } else { secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, secKeyData); } } catch (PgpException ex) { throw ex; } catch (global::System.Exception exception) { throw new PgpException("Exception encrypting key", exception); } }
internal PgpPrivateKey DoExtractPrivateKey(byte[] rawPassPhrase, bool clearPassPhrase) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (IsPrivateKeyEmpty) { return(null); } PublicKeyPacket publicKeyPacket = secret.PublicKeyPacket; try { byte[] array = ExtractKeyData(rawPassPhrase, clearPassPhrase); BcpgInputStream bcpgIn = BcpgInputStream.Wrap((Stream) new MemoryStream(array, false)); AsymmetricKeyParameter privateKey; switch (publicKeyPacket.Algorithm) { case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: { RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)publicKeyPacket.Key; RsaSecretBcpgKey rsaSecretBcpgKey = new RsaSecretBcpgKey(bcpgIn); RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = new RsaPrivateCrtKeyParameters(rsaSecretBcpgKey.Modulus, rsaPublicBcpgKey.PublicExponent, rsaSecretBcpgKey.PrivateExponent, rsaSecretBcpgKey.PrimeP, rsaSecretBcpgKey.PrimeQ, rsaSecretBcpgKey.PrimeExponentP, rsaSecretBcpgKey.PrimeExponentQ, rsaSecretBcpgKey.CrtCoefficient); privateKey = rsaPrivateCrtKeyParameters; break; } case PublicKeyAlgorithmTag.Dsa: { DsaPublicBcpgKey dsaPublicBcpgKey = (DsaPublicBcpgKey)publicKeyPacket.Key; DsaSecretBcpgKey dsaSecretBcpgKey = new DsaSecretBcpgKey(bcpgIn); DsaParameters parameters2 = new DsaParameters(dsaPublicBcpgKey.P, dsaPublicBcpgKey.Q, dsaPublicBcpgKey.G); privateKey = new DsaPrivateKeyParameters(dsaSecretBcpgKey.X, parameters2); break; } case PublicKeyAlgorithmTag.EC: privateKey = GetECKey("ECDH", bcpgIn); break; case PublicKeyAlgorithmTag.ECDsa: privateKey = GetECKey("ECDSA", bcpgIn); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: { ElGamalPublicBcpgKey elGamalPublicBcpgKey = (ElGamalPublicBcpgKey)publicKeyPacket.Key; ElGamalSecretBcpgKey elGamalSecretBcpgKey = new ElGamalSecretBcpgKey(bcpgIn); ElGamalParameters parameters = new ElGamalParameters(elGamalPublicBcpgKey.P, elGamalPublicBcpgKey.G); privateKey = new ElGamalPrivateKeyParameters(elGamalSecretBcpgKey.X, parameters); break; } default: throw new PgpException("unknown public key algorithm encountered"); } return(new PgpPrivateKey(KeyId, publicKeyPacket, privateKey)); } catch (PgpException ex) { throw ex; } catch (global::System.Exception exception) { throw new PgpException("Exception constructing key", exception); } }
private void doTestEnc( int size, int privateValueSize, IBigInteger g, IBigInteger p) { ElGamalParameters dhParams = new ElGamalParameters(p, g, privateValueSize); ElGamalKeyGenerationParameters ekgParams = new ElGamalKeyGenerationParameters(new SecureRandom(), dhParams); ElGamalKeyPairGenerator kpGen = new ElGamalKeyPairGenerator(); kpGen.Init(ekgParams); // // generate pair // IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); ElGamalPublicKeyParameters pu = (ElGamalPublicKeyParameters)pair.Public; ElGamalPrivateKeyParameters pv = (ElGamalPrivateKeyParameters)pair.Private; checkKeySize(privateValueSize, pv); ElGamalEngine e = new ElGamalEngine(); e.Init(true, pu); if (e.GetOutputBlockSize() != size / 4) { Fail(size + " GetOutputBlockSize() on encryption failed."); } byte[] message = Hex.Decode("5468697320697320612074657374"); byte[] pText = message; byte[] cText = e.ProcessBlock(pText, 0, pText.Length); e.Init(false, pv); if (e.GetOutputBlockSize() != (size / 8) - 1) { Fail(size + " GetOutputBlockSize() on decryption failed."); } pText = e.ProcessBlock(cText, 0, cText.Length); if (!Arrays.AreEqual(message, pText)) { Fail(size + " bit test failed"); } e.Init(true, pu); byte[] bytes = new byte[e.GetInputBlockSize() + 2]; try { e.ProcessBlock(bytes, 0, bytes.Length); Fail("out of range block not detected"); } catch (DataLengthException) { // expected } try { bytes[0] = (byte)0xff; e.ProcessBlock(bytes, 0, bytes.Length - 1); Fail("out of range block not detected"); } catch (DataLengthException) { // expected } try { bytes[0] = (byte)0x7f; e.ProcessBlock(bytes, 0, bytes.Length - 1); } catch (DataLengthException) { Fail("in range block failed"); } }