public Encrypted() { SecureRandom random = new SecureRandom(); this.Key = random.GenerateSeed(16); this.IV = random.GenerateSeed(16); this.Plain = string.Empty; }
public static void SetPassword(CT_SheetProtection xobj, String password, HashAlgorithm hashAlgo, String prefix) { if (password == null) { xobj.password = null; xobj.algorithmName = null; xobj.hashValue = null; xobj.saltValue = null; xobj.spinCount = null; return; } if (hashAlgo == null) { int hash = CryptoFunctions.CreateXorVerifier1(password); xobj.password = String.Format("{0:X4}", hash).ToUpper(); } else { SecureRandom random = new SecureRandom(); byte[] salt = random.GenerateSeed(16); int spinCount = 100000; byte[] hash = CryptoFunctions.HashPassword(password, hashAlgo, salt, spinCount, false); xobj.algorithmName = hashAlgo.jceId; xobj.hashValue = Convert.ToBase64String(hash); xobj.saltValue = Convert.ToBase64String(salt); xobj.spinCount = "" + spinCount; } }
private static double MeasureChiSquared(SecureRandom random, int rounds) { byte[] opts = random.GenerateSeed(2); int[] counts = new int[256]; byte[] bs = new byte[256]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[bs[b]]; } } byte mask = opts[0]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[bs[b] ^ mask]; } ++mask; } byte shift = opts[1]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[(byte)(bs[b] + shift)]; } ++shift; } int total = 3 * rounds; double chi2 = 0; for (int k = 0; k < counts.Length; ++k) { double diff = ((double)counts[k]) - total; double diff2 = diff * diff; chi2 += diff2; } chi2 /= total; return(chi2); }
public static string GeneratePassword() { SecureRandom random = new SecureRandom(); string password = random.GenerateSeed(64).ToBase64(); return(password); }
private static void Encrypt(IByteBuffer inputBuffer, bool toServer, ISession session, long messageId, int seqNumber, IByteBuffer output) { var messageBuffer = PooledByteBufferAllocator.Default.Buffer(); byte[] messageData; try { messageBuffer.WriteBytes(session.ServerSalt); messageBuffer.WriteLongLE((long)session.SessionId); messageBuffer.WriteLongLE(messageId); messageBuffer.WriteIntLE(seqNumber); messageBuffer.WriteIntLE(inputBuffer.ReadableBytes); messageBuffer.WriteBytes(inputBuffer); var randomPaddingLenght = Random.Next(1024 / 16) * 16 + 16 - messageBuffer.ReadableBytes % 16; messageBuffer.WriteBytes(Random.GenerateSeed(randomPaddingLenght)); messageData = messageBuffer.ToArray(); } finally { messageBuffer.SafeRelease(); } var messageKey = CalcMsgKey(session.AuthKey.Data, messageData); var aesKey = CalcKey(session.AuthKey.Data, messageKey, toServer); output.WriteLongLE((long)session.AuthKey.Id); output.WriteBytes(messageKey); output.WriteBytes(AES.EncryptAes(aesKey, messageData)); }
private byte[] EncodeBlock( byte[] inBytes, int inOff, int inLen) { byte[] block = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length]; // // copy in the message // Array.Copy(inBytes, inOff, block, block.Length - inLen, inLen); // // add sentinel // block[block.Length - inLen - 1] = 0x01; // // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0) // // // add the hash of the encoding params. // Array.Copy(defHash, 0, block, defHash.Length, defHash.Length); // // generate the seed. // byte[] seed = random.GenerateSeed(defHash.Length); // // mask the message block. // byte[] mask = maskGeneratorFunction1(seed, 0, seed.Length, block.Length - defHash.Length); for (int i = defHash.Length; i != block.Length; i++) { block[i] ^= mask[i - defHash.Length]; } // // add in the seed // Array.Copy(seed, 0, block, 0, defHash.Length); // // mask the seed. // mask = maskGeneratorFunction1( block, defHash.Length, block.Length - defHash.Length, defHash.Length); for (int i = 0; i != defHash.Length; i++) { block[i] ^= mask[i]; } return(engine.ProcessBlock(block, 0, block.Length)); }
public static SecureRandom GetSecureRandom() { SecureRandom random = new SecureRandom(); int rnd = CryptoHelper.PseudoRandomNumber(); random.SetSeed(random.GenerateSeed(rnd)); return(random); }
public void TestVmpcPrng() { SecureRandom random = new SecureRandom(new VmpcRandomGenerator()); random.SetSeed(random.GenerateSeed(32)); CheckSecureRandom(random); }
/// <summary> /// Class implementing Belare and Neven Multi-signature /// See "Multi-Signatures in the Plain Public-Key Model and a General Forking Lemma" /// - <see href="https://cseweb.ucsd.edu/~mihir/papers/multisignatures-ccs.pdf" /> /// - Port <see href="https://github.com/ElrondNetwork/elrond-node-prototype/blob/master/elrond-core/" /> /// </summary> /// <param name="secp256k1"></param> public MultiSignature(ISecp256k1 secp256k1) { _secp256k1 = secp256k1; _secureRandom = new SecureRandom(); var seed = _secureRandom.GenerateSeed(32); _secureRandom.SetSeed(seed); }
public static KeyStore GenerateKeystore(string password, string seed) { var secureRandom = new SecureRandom(); var privateKey = GenerateRandomPrivateKey(seed).ToString(16); var salt = secureRandom.GenerateSeed(16); const int cost = 8192; const int blockSize = 8; const int parallelization = 1; const int dkLength = 256; var decriptionKey = GenerateSCryptKey( GetBytes(password), salt, cost, blockSize, parallelization, dkLength); var iv = secureRandom.GenerateSeed(16); var ciphartext = BytesToHex(AesCtrEncrypt(privateKey.HexToByteArray(), iv, decriptionKey)); var mac = CalcSHA256InHex(BytesToHex(decriptionKey) + ciphartext); var keystore = new KeyStore { Cipher = "aes-128-ctr", Ciphertext = ciphartext, Id = Guid.NewGuid().ToString(), CipherParamIv = BytesToHex(iv), Kdf = "script", KdfParameters = new KdfParameters { DkLength = dkLength, N = cost, Salt = BytesToHex(salt), P = parallelization, R = blockSize }, Mac = mac }; return(keystore); }
/// Generates a new AES key having the desired [length]. // public static async Task<KeyParameter> generateAesKey(int length = 256) public static KeyParameter generateAesKey(int length = 256) { // Get a secure random SecureRandom mySecureRandom = _getSecureRandom(); // mySecureRandom.GenerateSeed generates byte[], so I must divide by 8 to have the intended number of bits (not by 16 as in Dart code) KeyParameter key = new KeyParameter(mySecureRandom.GenerateSeed(length / 8)); return(key); }
public string Encrypt(string plainText, byte[] key) { var random = new SecureRandom(); var iv = random.GenerateSeed(AesIvSize); var keyParameters = CreateKeyParameters(key, iv, GcmTagSize * 8); var cipher = CipherUtilities.GetCipher(_algorithm); cipher.Init(true, keyParameters); var plainTextData = Encoding.UTF8.GetBytes(plainText); var cipherText = cipher.DoFinal(plainTextData); return(PackCipherData(cipherText, iv)); }
private static SecureString GenerateNewMachineKey(int keySize) { var random = new SecureRandom(); random.SetSeed(random.GenerateSeed(128)); var machineKeyString = ""; for (var x = 0; x < keySize; x++) { machineKeyString += (char)random.Next(33, 126); } return(machineKeyString.ConvertToSecureString()); }
/** * Returns a random number generator, amcl.RAND, * initialized with a fresh seed. * * @return a random number generator */ public static RAND GetRand() { // construct a secure seed int seedLength = FIELD_BYTES; SecureRandom random = new SecureRandom(); byte[] seed = random.GenerateSeed(seedLength); // create a new amcl.RAND and initialize it with the generated seed RAND rng = new RAND(); rng.Clean(); rng.Seed(seedLength, seed); return(rng); }
public string GenerateRandom() { var symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); var r = new SecureRandom(); var res = r.GenerateSeed(40); var result = new StringBuilder(symbols.Length); foreach (var b in res) { result.Append(symbols[b % symbols.Length]); } return(result.ToString()); }
public static RsaKeyPair RsaGenerateKeyPair(byte[] Seed) { RsaKeyPairGenerator rsaGenerator = new RsaKeyPairGenerator(); string privatePem = ""; string publicPem = ""; var rng = new SecureRandom(); byte[] seed = Seed; if (seed == null) { seed = rng.GenerateSeed(4096); } //rng.SetSeed(seed); rng = new SecureRandom(seed); rsaGenerator.Init(new KeyGenerationParameters(rng, 2048)); var keyPair = rsaGenerator.GenerateKeyPair(); //if (!Directory.Exists(privateKeyFilePath)) { Directory.CreateDirectory(privateKeyFilePath); } using (TextWriter privateKeyTextWriter = new StringWriter()) { PemWriter pemWriter = new PemWriter(privateKeyTextWriter); pemWriter.WriteObject(keyPair.Private); pemWriter.Writer.Flush(); //File.WriteAllText(privateKeyFilePath + hash + ".private.pem", privateKeyTextWriter.ToString()); privatePem = privateKeyTextWriter.ToString(); } //if (!Directory.Exists(publicKeyFilePath)) { Directory.CreateDirectory(publicKeyFilePath); } using (TextWriter publicKeyTextWriter = new StringWriter()) { PemWriter pemWriter = new PemWriter(publicKeyTextWriter); pemWriter.WriteObject(keyPair.Public); pemWriter.Writer.Flush(); //File.WriteAllText(publicKeyFilePath + hash + ".public.pem", publicKeyTextWriter.ToString()); publicPem = publicKeyTextWriter.ToString(); } return(new RsaKeyPair() { PublicKey = publicPem, PrivateKey = privatePem, Timestamp = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds }); }
static void Main(string[] args) { //rSAKeyPairGenerator generates the RSA key pair based on the random number and strength of the key required RsaKeyPairGenerator rSAKeyPair = new RsaKeyPairGenerator(); SecureRandom secureRandom = new SecureRandom(); secureRandom.SetSeed(secureRandom.GenerateSeed(1000)); rSAKeyPair.Init(new KeyGenerationParameters(secureRandom, 2048)); AsymmetricCipherKeyPair keyPair = rSAKeyPair.GenerateKeyPair(); //Extract private/public key from the pair RsaKeyParameters privateKey = keyPair.Private as RsaKeyParameters; RsaKeyParameters publicKey = keyPair.Public as RsaKeyParameters; //print public & private key in pem format CreatePem(publicKey); CreatePem(privateKey); }
static Security() { try { var cipher = new GcmBlockCipher(new AesEngine()); sr.SetSeed(sr.GenerateSeed(16)); } catch (NoSuchAlgorithmException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } catch (NotSupportedException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } }
private byte[] EncodeBlock(byte[] inBytes, int inOff, int inLen) { byte[] array = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length]; Array.Copy(inBytes, inOff, array, array.Length - inLen, inLen); array[array.Length - inLen - 1] = 1; Array.Copy(defHash, 0, array, defHash.Length, defHash.Length); byte[] array2 = random.GenerateSeed(defHash.Length); byte[] array3 = maskGeneratorFunction1(array2, 0, array2.Length, array.Length - defHash.Length); for (int i = defHash.Length; i != array.Length; i++) { array[i] ^= array3[i - defHash.Length]; } Array.Copy(array2, 0, array, 0, defHash.Length); array3 = maskGeneratorFunction1(array, defHash.Length, array.Length - defHash.Length, defHash.Length); for (int j = 0; j != defHash.Length; j++) { array[j] ^= array3[j]; } return(engine.ProcessBlock(array, 0, array.Length)); }
public byte[] GetEntropy() { return(_sr.GenerateSeed((bitsRequired + 7) / 8)); }
public static string Random() { return(Hash(SecureRand.GenerateSeed(256))); }
public void TestVmpcPrng() { SecureRandom random = new SecureRandom(new VmpcRandomGenerator()); random.SetSeed(random.GenerateSeed(32)); CheckSecureRandom(random); }
/// <summary> /// Safely get Crypto Random byte array at the size you desire. /// </summary> /// <param name="size">Size of the crypto random byte array to build</param> /// <param name="seedStretchingIterations">Optional parameter to specify how many SHA512 passes occur over our seed before we use it. Higher value is greater security but uses more computational power. If random byte generation is taking too long try specifying values lower than the default of 5000. You can set 0 to turn off stretching</param> /// <returns>A byte array of completely random bytes</returns> public static byte[] GetRandomBytes(int size, int seedStretchingIterations = 5000) { //varies from system to system, a tiny amount of entropy, tiny int processorCount = System.Environment.ProcessorCount; //another tiny amount of entropy due to the varying nature of thread id int currentThreadId = System.Environment.CurrentManagedThreadId; //a GUID is considered unique so also provides some entropy byte[] guidBytes = Guid.NewGuid().ToByteArray(); //this combined with DateTime.Now is the default seed in BouncyCastles SecureRandom byte[] threadedSeedBytes = new ThreadedSeedGenerator().GenerateSeed(24, true); byte[] output = new byte[size]; //if for whatever reason it says 0 or less processors just make it 16 if (processorCount <= 0) { processorCount = 16; } //if some fool trys to set stretching to < 0 we protect them from themselves if (seedStretchingIterations < 0) { seedStretchingIterations = 0; } //we create a SecureRandom based off SHA256 just to get a random int which will be used to determine what bytes to "take" from our built seed hash and then rehash those taken seed bytes using a KDF (key stretching) such that it would slow down anyone trying to rebuild private keys from common seeds. SecureRandom seedByteTakeDetermine = SecureRandom.GetInstance("SHA256PRNG"); guidBytes = HmacSha512Digest(guidBytes, 0, guidBytes.Length, MergeByteArrays(threadedSeedBytes, UTF8Encoding.UTF8.GetBytes(Convert.ToString(System.Environment.TickCount)))); try { seedByteTakeDetermine.SetSeed(((DateTime.Now.Ticks - System.Environment.TickCount) * processorCount) + currentThreadId); seedByteTakeDetermine.SetSeed(guidBytes); seedByteTakeDetermine.SetSeed(seedByteTakeDetermine.GenerateSeed(1 + currentThreadId)); seedByteTakeDetermine.SetSeed(threadedSeedBytes); } catch { try { //if the number is too big or causes an error or whatever we will failover to this, as it's not our main source of random bytes and not used in the KDF stretching it's ok. seedByteTakeDetermine.SetSeed((DateTime.Now.Ticks - System.Environment.TickCount) + currentThreadId); seedByteTakeDetermine.SetSeed(guidBytes); seedByteTakeDetermine.SetSeed(seedByteTakeDetermine.GenerateSeed(1 + currentThreadId)); seedByteTakeDetermine.SetSeed(threadedSeedBytes); } catch { //if again the number is too big or causes an error or whatever we will failover to this, as it's not our main source of random bytes and not used in the KDF stretching it's ok. seedByteTakeDetermine.SetSeed(DateTime.Now.Ticks - System.Environment.TickCount); seedByteTakeDetermine.SetSeed(guidBytes); seedByteTakeDetermine.SetSeed(seedByteTakeDetermine.GenerateSeed(1 + currentThreadId)); seedByteTakeDetermine.SetSeed(threadedSeedBytes); } } //hardened seed byte[] toHashForSeed; try { toHashForSeed = BitConverter.GetBytes(((processorCount - seedByteTakeDetermine.Next(0, processorCount)) * System.Environment.TickCount) * currentThreadId); } catch { try { //if the number was too large or something we failover to this toHashForSeed = BitConverter.GetBytes(((processorCount - seedByteTakeDetermine.Next(0, processorCount)) + System.Environment.TickCount) * currentThreadId); } catch { //if the number was again too large or something we failover to this toHashForSeed = BitConverter.GetBytes(((processorCount - seedByteTakeDetermine.Next(0, processorCount)) + System.Environment.TickCount) + currentThreadId); } } toHashForSeed = Sha512Digest(toHashForSeed, 0, toHashForSeed.Length); toHashForSeed = MergeByteArrays(toHashForSeed, guidBytes); toHashForSeed = MergeByteArrays(toHashForSeed, BitConverter.GetBytes(currentThreadId)); toHashForSeed = MergeByteArrays(toHashForSeed, BitConverter.GetBytes(DateTime.UtcNow.Ticks)); toHashForSeed = MergeByteArrays(toHashForSeed, BitConverter.GetBytes(DateTime.Now.Ticks)); toHashForSeed = MergeByteArrays(toHashForSeed, BitConverter.GetBytes(System.Environment.TickCount)); toHashForSeed = MergeByteArrays(toHashForSeed, BitConverter.GetBytes(processorCount)); toHashForSeed = MergeByteArrays(toHashForSeed, threadedSeedBytes); toHashForSeed = Sha512Digest(toHashForSeed, 0, toHashForSeed.Length); //we grab a random amount of bytes between 24 and 64 to rehash make a new set of 64 bytes, using guidBytes as hmackey toHashForSeed = Sha512Digest(HmacSha512Digest(toHashForSeed, 0, seedByteTakeDetermine.Next(24, 64), guidBytes), 0, 64); seedByteTakeDetermine.SetSeed(currentThreadId + (DateTime.Now.Ticks - System.Environment.TickCount)); //by making the iterations also random we are again making it hard to determin our seed by brute force int iterations = seedStretchingIterations - (seedByteTakeDetermine.Next(0, (seedStretchingIterations / seedByteTakeDetermine.Next(9, 100)))); //here we use key stretching techniques to make it harder to replay the random seed values by forcing computational time up byte[] seedMaterial = Rfc2898_pbkdf2_hmacsha512.PBKDF2(toHashForSeed, seedByteTakeDetermine.GenerateSeed(64), iterations); //build a SecureRandom object that uses Sha512 to provide randomness and we will give it our created above hardened seed SecureRandom secRand = new SecureRandom(new Org.BouncyCastle.Crypto.Prng.DigestRandomGenerator(new Sha512Digest())); //set the seed that we created just above secRand.SetSeed(seedMaterial); //generate more seed materisal secRand.SetSeed(currentThreadId); secRand.SetSeed(MergeByteArrays(guidBytes, threadedSeedBytes)); secRand.SetSeed(secRand.GenerateSeed(1 + secRand.Next(64))); //add our prefab seed again onto the previous material just to be sure the above statements are adding and not clobbering seed material secRand.SetSeed(seedMaterial); //here we derive our random bytes secRand.NextBytes(output, 0, size); return(output); }
public static byte[] GetSecureRandomByteArray(int size) { SecureRandom random = new SecureRandom(); return(random.GenerateSeed(size)); }
protected internal static string GenId() { SecureRandom random = new SecureRandom(); return(random.GenerateSeed(64).ToBase64().Sha256()); }
//static System.Security.Cryptography.RIPEMD160 ripemd160 = System.Security.Cryptography.RIPEMD160.Create(); public static byte[] CreatePrivateKey() { var random = new SecureRandom(); return(random.GenerateSeed(32)); }
protected virtual byte[] engineGenerateKey() { return(random.GenerateSeed(strength)); }
private static double MeasureChiSquared(SecureRandom random, int rounds) { byte[] opts = random.GenerateSeed(2); int[] counts = new int[256]; byte[] bs = new byte[256]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[bs[b]]; } } byte mask = opts[0]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[bs[b] ^ mask]; } ++mask; } byte shift = opts[1]; for (int i = 0; i < rounds; ++i) { random.NextBytes(bs); for (int b = 0; b < 256; ++b) { ++counts[(byte)(bs[b] + shift)]; } ++shift; } int total = 3 * rounds; double chi2 = 0; for (int k = 0; k < counts.Length; ++k) { double diff = ((double) counts[k]) - total; double diff2 = diff * diff; chi2 += diff2; } chi2 /= total; return chi2; }
private static byte[] GetInitializationVector() { var random = new SecureRandom(); return(random.GenerateSeed(AesIvSize)); }
/** * Sets the XORed or hashed password * * @param xobj the xmlbeans object which Contains the password attributes * @param password the password, if null, the password attributes will be Removed * @param hashAlgo the hash algorithm, if null the password will be XORed * @param prefix the prefix of the password attributes, may be null */ public static void SetPassword(XmlNode xobj, String password, HashAlgorithm hashAlgo, String prefix) { XPathNavigator cur = xobj.CreateNavigator(); if (password == null) { //dose the prefix is namespace? check it!!! if (cur.MoveToAttribute("password", prefix)) { cur.DeleteSelf(); } if (cur.MoveToAttribute("algorithmName", prefix)) { cur.DeleteSelf(); } if (cur.MoveToAttribute("hashValue", prefix)) { cur.DeleteSelf(); } if (cur.MoveToAttribute("saltValue", prefix)) { cur.DeleteSelf(); } if (cur.MoveToAttribute("spinCount", prefix)) { cur.DeleteSelf(); } return; } //cur.ToFirstContentToken(); if (hashAlgo == null) { int hash = CryptoFunctions.CreateXorVerifier1(password); cur.CreateAttribute(prefix, "password", null, String.Format("{0:X4}", hash).ToUpper()); //cur.InsertAttributeWithValue(GetAttrName(prefix, "password"), // String.Format("{0:X}", hash).ToUpper()); } else { SecureRandom random = new SecureRandom(); byte[] salt = random.GenerateSeed(16); // Iterations specifies the number of times the hashing function shall be iteratively run (using each // iteration's result as the input for the next iteration). int spinCount = 100000; // Implementation Notes List: // --> In this third stage, the reversed byte order legacy hash from the second stage shall // be Converted to Unicode hex string representation byte[] hash = CryptoFunctions.HashPassword(password, hashAlgo, salt, spinCount, false); cur.CreateAttribute(prefix, "algorithmName", null, hashAlgo.jceId); cur.CreateAttribute(prefix, "hashValue", null, Convert.ToBase64String(hash)); cur.CreateAttribute(prefix, "saltValue", null, Convert.ToBase64String(salt)); cur.CreateAttribute(prefix, "spinCount", null, "" + spinCount); //cur.InsertAttributeWithValue(GetAttrName(prefix, "algorithmName"), hashAlgo.jceId); //cur.InsertAttributeWithValue(GetAttrName(prefix, "hashValue"), Convert.ToBase64String(hash)); //cur.InsertAttributeWithValue(GetAttrName(prefix, "saltValue"), Convert.ToBase64String(salt)); //cur.InsertAttributeWithValue(GetAttrName(prefix, "spinCount"), "" + spinCount); } //cur.Dispose(); }
public static string GenerateId() { SecureRandom random = new SecureRandom(); return(random.GenerateSeed(64).ToBase64().Sha256()); }
private Zone SignWithNSec3(DateTime inception, DateTime expiration, List <DnsKeyRecord> zoneSigningKeys, List <DnsKeyRecord> keySigningKeys, NSec3HashAlgorithm nsec3Algorithm, int nsec3Iterations, byte[] nsec3Salt, bool nsec3OptOut) { var soaRecord = _records.OfType <SoaRecord>().First(); var subZoneNameserver = _records.Where(x => (x.RecordType == RecordType.Ns) && (x.Name != Name)).ToList(); var subZones = subZoneNameserver.Select(x => x.Name).Distinct().ToList(); var unsignedRecords = _records.Where(x => subZones.Any(y => x.Name.IsSubDomainOf(y))).ToList(); // glue records if (nsec3OptOut) { unsignedRecords = unsignedRecords.Union(subZoneNameserver.Where(x => !_records.Any(y => (y.RecordType == RecordType.Ds) && (y.Name == x.Name)))).ToList(); // delegations without DS record } var recordsByName = _records.Except(unsignedRecords).Union(zoneSigningKeys).Union(keySigningKeys).GroupBy(x => x.Name).Select(x => new Tuple <DomainName, List <DnsRecordBase> >(x.Key, x.OrderBy(y => y.RecordType == RecordType.Soa ? -1 : (int)y.RecordType).ToList())).OrderBy(x => x.Item1).ToList(); byte nsec3RecordFlags = (byte)(nsec3OptOut ? 1 : 0); Zone res = new Zone(Name, Count * 3); List <NSec3Record> nSec3Records = new List <NSec3Record>(Count); if (nsec3Salt == null) { nsec3Salt = _secureRandom.GenerateSeed(8); } recordsByName[0].Item2.Add(new NSec3ParamRecord(soaRecord.Name, soaRecord.RecordClass, 0, nsec3Algorithm, 0, (ushort)nsec3Iterations, nsec3Salt)); HashSet <DomainName> allNames = new HashSet <DomainName>(); for (int i = 0; i < recordsByName.Count; i++) { List <RecordType> recordTypes = new List <RecordType>(); DomainName currentName = recordsByName[i].Item1; foreach (var recordsByType in recordsByName[i].Item2.GroupBy(x => x.RecordType)) { List <DnsRecordBase> records = recordsByType.ToList(); recordTypes.Add(recordsByType.Key); res.AddRange(records); // do not sign nameserver delegations for sub zones if ((records[0].RecordType == RecordType.Ns) && (currentName != Name)) { continue; } recordTypes.Add(RecordType.RrSig); foreach (var key in zoneSigningKeys) { res.Add(new RrSigRecord(records, key, inception, expiration)); } if (records[0].RecordType == RecordType.DnsKey) { foreach (var key in keySigningKeys) { res.Add(new RrSigRecord(records, key, inception, expiration)); } } } byte[] hash = recordsByName[i].Item1.GetNSec3Hash(nsec3Algorithm, nsec3Iterations, nsec3Salt); nSec3Records.Add(new NSec3Record(DomainName.ParseFromMasterfile(hash.ToBase32HexString()) + Name, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, nsec3Algorithm, nsec3RecordFlags, (ushort)nsec3Iterations, nsec3Salt, hash, recordTypes)); allNames.Add(currentName); for (int j = currentName.LabelCount - Name.LabelCount; j > 0; j--) { DomainName possibleNonTerminal = currentName.GetParentName(j); if (!allNames.Contains(possibleNonTerminal)) { hash = possibleNonTerminal.GetNSec3Hash(nsec3Algorithm, nsec3Iterations, nsec3Salt); nSec3Records.Add(new NSec3Record(DomainName.ParseFromMasterfile(hash.ToBase32HexString()) + Name, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, nsec3Algorithm, nsec3RecordFlags, (ushort)nsec3Iterations, nsec3Salt, hash, new List <RecordType>())); allNames.Add(possibleNonTerminal); } } } nSec3Records = nSec3Records.OrderBy(x => x.Name).ToList(); byte[] firstNextHashedOwnerName = nSec3Records[0].NextHashedOwnerName; for (int i = 1; i < nSec3Records.Count; i++) { nSec3Records[i - 1].NextHashedOwnerName = nSec3Records[i].NextHashedOwnerName; } nSec3Records[nSec3Records.Count - 1].NextHashedOwnerName = firstNextHashedOwnerName; foreach (var nSec3Record in nSec3Records) { res.Add(nSec3Record); foreach (var key in zoneSigningKeys) { res.Add(new RrSigRecord(new List <DnsRecordBase>() { nSec3Record }, key, inception, expiration)); } } res.AddRange(unsignedRecords); return(res); }