// Generate a random key value. public override void GenerateKey() { byte[] key = new byte [8]; do { CryptoMethods.GenerateRandom(key, 0, 8); }while(CryptoMethods.IsSemiWeakKey(key, 0) || CryptoMethods.IsWeakKey(key, 0)); if (KeyValue != null) { // Clear the previous key value. Array.Clear(KeyValue, 0, KeyValue.Length); } KeyValue = key; }
// Get non-zero random data. public override void GetNonZeroBytes(byte[] data) { int index; // Get the initial random data. CryptoMethods.GenerateRandom(data, 0, data.Length); // Replace zero bytes with new random data. for (index = 0; index < data.Length; ++index) { while (data[index] == 0) { CryptoMethods.GenerateRandom(data, index, 1); } } }
// Finalize the hash and return the final hash value. protected override byte[] HashFinal() { // Bail out if the runtime engine does not have a provider. if (state == IntPtr.Zero) { throw new CryptographicException (_("Crypto_NoProvider"), "RIPEMD160"); } // Compute the hash and return it. byte[] hash = new byte [64]; lock (this) { CryptoMethods.HashFinal(state, hash); } return(hash); }
/// <summary> /// Save a refresh token /// Returns the refresh token id /// </summary> /// <param name="refreshToken"></param> /// <returns>Refresh token id</returns> public async Task <String> SaveRefreshTokenAsync(RefreshTokenModel refreshToken) { var refreshTokenId = Guid.NewGuid().ToString("n"); _context.RefreshTokens.Add(new RefreshTokens { ClientId = "notneeded", ExpiresUtc = refreshToken.ExpiresUtc, IssuedUtc = refreshToken.IssuedUtc, ProtectedTicket = refreshToken.AccessToken, Subject = refreshToken.Subject, TokenIdHash = CryptoMethods.GetSHA512Hash(refreshTokenId) }); await _context.SaveChangesAsync(); return(refreshTokenId); }
// Determine if a TripleDES key value is "weak". public static bool IsWeakKey(byte[] rgbKey) { if (rgbKey == null || (rgbKey.Length != 16 && rgbKey.Length != 24)) { throw new CryptographicException (_("Crypto_InvalidKeySize"), ((rgbKey == null) ? 0 : rgbKey.Length).ToString()); } if (rgbKey.Length == 16) { return(CryptoMethods.SameKey(rgbKey, 0, rgbKey, 8)); } else { return(CryptoMethods.SameKey(rgbKey, 0, rgbKey, 8) || CryptoMethods.SameKey(rgbKey, 8, rgbKey, 16)); } }
// Dispose this object. protected override void Dispose(bool disposing) { if (disposing) { lock (this) { if (state != IntPtr.Zero) { CryptoMethods.HashFree(state); state = IntPtr.Zero; } } } else if (state != IntPtr.Zero) { CryptoMethods.HashFree(state); state = IntPtr.Zero; } }
// Transform an input block into an output block. public static int TransformBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { int blockSize = transform.blockSize; int feedbackSize = transform.feedbackBlockSize; byte[] iv = transform.iv; IntPtr state = transform.state; int offset = outputOffset; byte[] tempBuffer = transform.tempBuffer; int tempSize = transform.tempSize; // Process all of the bytes in the input. while (inputCount > 0) { // Encrypt the queue if we need more keystream data. if (tempSize >= feedbackSize) { CryptoMethods.Encrypt(state, tempBuffer, feedbackSize, tempBuffer, 0); tempSize = 0; } // XOR the plaintext byte with the next keystream byte. outputBuffer[offset++] = (byte)(tempBuffer[tempSize] ^ inputBuffer[inputOffset++]); --inputCount; // Feed the keystream byte back into the queue. tempBuffer[tempSize + blockSize] = tempBuffer[tempSize]; ++tempSize; } transform.tempSize = tempSize; // Finished. return(offset - outputOffset); }
/// <summary> /// Authenticate an admin /// Returns the admin with roles if successful, otherwise null /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <returns></returns> public async Task <Admins> AuthenticateAsync(String username, String password) { var admin = await _context.Admins.Include(m => m.Roles).SingleOrDefaultAsync(o => (o.Username == username || o.Email == username) && o.Status == 1); if (admin != null) { var result = CryptoMethods.VerifyHashedPassword(admin.Password, password); if (result == PasswordVerificationResult.Success) { return(admin); } else if (result == PasswordVerificationResult.SuccessRehashNeeded) { admin.Password = new PasswordHasher <Admins>().HashPassword(null, password); await _context.SaveChangesAsync(); return(admin); } } return(null); }
// Apply the private key to a value. private byte[] ApplyPrivate(byte[] value) { if (rsaParams.P != null) { // Use the Chinese Remainder Theorem exponents. // Based on the description in PKCS #1. byte[] m1 = CryptoMethods.NumPow(value, rsaParams.DP, rsaParams.P); byte[] m2 = CryptoMethods.NumPow(value, rsaParams.DQ, rsaParams.Q); byte[] diff = CryptoMethods.NumSub(m1, m2, null); byte[] h = CryptoMethods.NumMul(diff, rsaParams.InverseQ, rsaParams.P); byte[] prod = CryptoMethods.NumMul(rsaParams.Q, h, null); byte[] m = CryptoMethods.NumAdd(m2, prod, null); // Clear all temporary values. Array.Clear(m1, 0, m1.Length); Array.Clear(m2, 0, m2.Length); Array.Clear(diff, 0, diff.Length); Array.Clear(h, 0, h.Length); Array.Clear(prod, 0, prod.Length); // Return the decrypted message. return(m); } else if (rsaParams.D != null) { // Use the private exponent directly. return(CryptoMethods.NumPow(value, rsaParams.D, rsaParams.Modulus)); } else { // Insufficient parameters for private key operations. throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } }
public RSACryptoServiceProvider(int dwKeySize, CspParameters parameters) { byte[] key; int result; // See "DSACryptoServiceProvider" for explainatory comments. if (parameters != null && parameters.KeyContainerName != null) { // Attempt to get an RSA key from the user's keychain. key = CryptoMethods.GetKey(CryptoMethods.RSAEncrypt, parameters.KeyContainerName, parameters.Flags, out result); if (key != null) { // The "ASN1ToPublic" method will determine if // the key is X.509, bare public, or private. rsaParams.ASN1ToPublic(key, 0, key.Length); Array.Clear(key, 0, key.Length); persistKey = true; } else if (result == CryptoMethods.UnknownKey) { throw new CryptographicException (_("Crypto_UnknownKey"), parameters.KeyContainerName); } else if (result == CryptoMethods.NotPermitted) { throw new CryptographicException (_("Crypto_NoKeyAccess"), parameters.KeyContainerName); } else if (result == CryptoMethods.GenerateKey) { // Generate a new key for the user. // TODO } } }
// Transform an input block into an output block. public static int TransformBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { int blockSize = transform.blockSize; IntPtr state = transform.state; int offset = outputOffset; // Process all of the blocks in the input. while (inputCount >= blockSize) { CryptoMethods.Encrypt(state, inputBuffer, inputOffset, outputBuffer, offset); inputOffset += blockSize; inputCount -= blockSize; offset += blockSize; } // Finished. return(offset - outputOffset); }
private void Dispose(bool disposing) { if (state != IntPtr.Zero) { CryptoMethods.SymmetricFree(state); state = IntPtr.Zero; } if (state2 != IntPtr.Zero) { CryptoMethods.SymmetricFree(state2); state2 = IntPtr.Zero; } if (tempBuffer != null) { Array.Clear(tempBuffer, 0, tempBuffer.Length); } tempSize = 0; if (iv != null) { // Usually not sensitive, but let's be paranoid anyway. Array.Clear(iv, 0, iv.Length); } }
public void BasicEnumerateStores() { string localMachineName = #if DESKTOP @"\\" + Environment.MachineName; #else // Haven't found an easy way to find the local machine name in a portable assembly. You can get the environment variable, // but that only works if you run on desktop, not as a Windows Store App. All of the suggested alternatives for WinRT aren't available // in the PCL surface area. Manually putting the machine name in works. null; #endif var localMachine = CryptoMethods.EnumerateSystemStores(SystemStoreLocation.CERT_SYSTEM_STORE_LOCAL_MACHINE); localMachine.Should().NotBeEmpty(); var localMachineByName = CryptoMethods.EnumerateSystemStores(SystemStoreLocation.CERT_SYSTEM_STORE_LOCAL_MACHINE, localMachineName); if (localMachineName != null) { localMachineByName.Should().OnlyContain(x => x.Name.StartsWith(localMachineName, StringComparison.Ordinal), "when specifying the machine name they should come back with the name"); } localMachineByName.Should().Equal(localMachine, (s1, s2) => s1.Name.EndsWith(s2.Name, StringComparison.Ordinal), "names should be the same whether or not we get local by name"); }
// Transform an input block into an output block. public static int TransformBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { int blockSize = transform.blockSize; byte[] iv = transform.iv; IntPtr state = transform.state; byte[] tempBuffer = transform.tempBuffer; int offset = outputOffset; int index; // Process a left-over block from last time. if (transform.tempSize > 0 && inputCount > 0) { // Decrypt the ciphertext to get the plaintext // xor'ed with the IV. CryptoMethods.Decrypt(state, tempBuffer, blockSize, tempBuffer, 0); // XOR the IV with the temporary buffer to get plaintext. for (index = blockSize - 1; index >= 0; --index) { outputBuffer[offset + index] = (byte)(iv[index] ^ tempBuffer[index]); } // Copy the original ciphertext to the IV. Array.Copy(tempBuffer, blockSize, iv, 0, blockSize); // Advance to the next block and clear the temporary block. offset += blockSize; transform.tempSize = 0; for (index = 2 * blockSize - 1; index >= blockSize; --index) { tempBuffer[index] = (byte)0x00; } } // Process all of the blocks in the input, minus one. while (inputCount > blockSize) { // Decrypt the ciphertext to get the plaintext // xor'ed with the IV. CryptoMethods.Decrypt(state, inputBuffer, inputOffset, tempBuffer, 0); // XOR the IV with the temporary buffer to get plaintext. for (index = blockSize - 1; index >= 0; --index) { outputBuffer[offset + index] = (byte)(iv[index] ^ tempBuffer[index]); } // Copy the original ciphertext to the IV. Array.Copy(inputBuffer, inputOffset, iv, 0, blockSize); // Advance to the next block. inputOffset += blockSize; inputCount -= blockSize; offset += blockSize; } // Save the last block for next time. if (inputCount > 0) { Array.Copy(inputBuffer, inputOffset, tempBuffer, blockSize, inputCount); transform.tempSize = inputCount; } // Clear the temporary buffer to protect sensitive data. for (index = blockSize - 1; index >= 0; --index) { tempBuffer[index] = (byte)0x00; } // Finished. return(offset - outputOffset); }
// Generate a random initialization vector. public override void GenerateIV() { byte[] iv = new byte [16]; CryptoMethods.GenerateRandom(iv, 0, 16); IVValue = iv; }
// Constructor. internal CryptoAPITransform(int algorithm, byte[] iv, byte[] key, int blockSize, int feedbackBlockSize, CipherMode mode, PaddingMode padding, bool encrypt) { // Initialize the common state. if (iv != null) { this.iv = (byte[])(iv.Clone()); } else { this.iv = null; } this.blockSize = blockSize / 8; this.feedbackBlockSize = feedbackBlockSize / 8; this.padding = padding; this.mode = mode; // Determine which processing methods to use based on the // mode and the encrypt/decrypt flag. switch (mode) { case CipherMode.CBC: { // Cipher Block Chaining Mode. if (encrypt) { state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (CBCEncrypt.TransformBlock); processFinal = new ProcessFinal (CBCEncrypt.TransformFinalBlock); } else { CBCDecrypt.Initialize(this); state = CryptoMethods.DecryptCreate(algorithm, key); processBlock = new ProcessBlock (CBCDecrypt.TransformBlock); processFinal = new ProcessFinal (CBCDecrypt.TransformFinalBlock); } } break; case CipherMode.ECB: { // Electronic Code Book Mode. if (encrypt) { state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (ECBEncrypt.TransformBlock); processFinal = new ProcessFinal (ECBEncrypt.TransformFinalBlock); } else { ECBDecrypt.Initialize(this); state = CryptoMethods.DecryptCreate(algorithm, key); processBlock = new ProcessBlock (ECBDecrypt.TransformBlock); processFinal = new ProcessFinal (ECBDecrypt.TransformFinalBlock); } } break; case CipherMode.OFB: { // Output Feed Back Mode. OFBEncrypt.Initialize(this); state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (OFBEncrypt.TransformBlock); processFinal = new ProcessFinal (OFBEncrypt.TransformFinalBlock); } break; case CipherMode.CFB: { // Cipher Feed Back Mode. if (encrypt) { CFBEncrypt.Initialize(this); state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (CFBEncrypt.TransformBlock); processFinal = new ProcessFinal (CFBEncrypt.TransformFinalBlock); } else { CFBDecrypt.Initialize(this); state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (CFBDecrypt.TransformBlock); processFinal = new ProcessFinal (CFBDecrypt.TransformFinalBlock); } } break; case CipherMode.CTS: { // Cipher Text Stealing Mode. if (encrypt) { CTSEncrypt.Initialize(this); state = CryptoMethods.EncryptCreate(algorithm, key); processBlock = new ProcessBlock (CTSEncrypt.TransformBlock); processFinal = new ProcessFinal (CTSEncrypt.TransformFinalBlock); } else { // We need an encryptor as well to handle // streams with only a single block in them. CTSDecrypt.Initialize(this); state = CryptoMethods.DecryptCreate(algorithm, key); state2 = CryptoMethods.EncryptCreate (algorithm, key); processBlock = new ProcessBlock (CTSDecrypt.TransformBlock); processFinal = new ProcessFinal (CTSDecrypt.TransformFinalBlock); } } break; } }
// Transform the final input block. public static byte[] TransformFinalBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount) { int blockSize = transform.blockSize; byte[] iv = transform.iv; IntPtr state = transform.state; int offset; byte[] tempBuffer = transform.tempBuffer; byte[] outputBuffer; int tempSize; int index; // Allocate the output buffer. outputBuffer = new byte [inputCount + transform.tempSize]; // Process as many full blocks as possible. index = inputCount - (inputCount % blockSize); offset = TransformBlock(transform, inputBuffer, inputOffset, index, outputBuffer, 0); inputOffset += index; inputCount -= index; // Flush the first block if we need the extra space. tempSize = transform.tempSize; if (tempSize > blockSize && inputCount > 0) { // Decrypt the ciphertext block and XOR with the IV. CryptoMethods.Decrypt(state, tempBuffer, blockSize, tempBuffer, 0); for (index = blockSize - 1; index >= 0; --index) { tempBuffer[index] ^= iv[index]; } // Copy the original ciphertext to the IV. Array.Copy(tempBuffer, blockSize, iv, 0, blockSize); // Copy the plaintext into place. Array.Copy(tempBuffer, 0, outputBuffer, offset, blockSize); // Advance to the next output block. offset += blockSize; // Shift the second block down to the first position. Array.Copy(tempBuffer, blockSize * 2, tempBuffer, blockSize, blockSize); tempSize -= blockSize; } // Copy the remainder of the data into the temporary buffer. Array.Copy(inputBuffer, inputOffset, tempBuffer, tempSize + blockSize, inputCount); tempSize += inputCount; // "Applied Cryptography" describes Cipher Text Stealing // as taking two blocks to generate the short end-point. // If we less than one block, then use CFB instead. if (tempSize < blockSize) { // Decrypt the single block in CFB mode. CryptoMethods.Encrypt(transform.state2, iv, 0, iv, 0); for (index = 0; index < tempSize; ++index) { outputBuffer[offset + index] = (byte)(iv[index] ^ tempBuffer[index + blockSize]); } } else { // Decrypt the second last ciphertext block. CryptoMethods.Decrypt(state, tempBuffer, blockSize, tempBuffer, blockSize); // Rebuild the ciphertext for the last block. for (index = inputCount; index < blockSize; ++index) { tempBuffer[blockSize * 2 + index] = tempBuffer[blockSize + index]; } // Get the last plaintext block from the second // last ciphertext block. for (index = inputCount - 1; index >= 0; --index) { outputBuffer[offset + blockSize + index] = (byte)(tempBuffer[blockSize + index] ^ tempBuffer[blockSize * 2 + index]); } // Decrypt the last ciphertext block that we rebuilt. CryptoMethods.Decrypt(state, tempBuffer, blockSize * 2, tempBuffer, 0); // XOR the block with the IV to get the second // last plaintext block. for (index = blockSize - 1; index >= 0; --index) { outputBuffer[offset + index] = (byte)(iv[index] ^ tempBuffer[index]); } } // Finished. return(outputBuffer); }
/// <summary> /// Get a /// </summary> /// <param name="refreshTokenId"></param> /// <returns></returns> public async Task <RefreshTokenModel> GetRefreshTokenAsync(String refreshTokenId) { var token = await _context.RefreshTokens.SingleOrDefaultAsync(o => o.TokenIdHash == CryptoMethods.GetSHA512Hash(refreshTokenId) && o.ExpiresUtc >= DateTime.UtcNow); return(token != null ? new RefreshTokenModel { ExpiresUtc = token.ExpiresUtc, IssuedUtc = token.IssuedUtc, AccessToken = token.ProtectedTicket, Subject = token.Subject } : null); }
// Get random data. public override void GetBytes(byte[] data) { CryptoMethods.GenerateRandom(data, 0, data.Length); }
// Verify a DSA signature. public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { // Validate the parameters. if (rgbHash == null) { throw new ArgumentNullException("rgbHash"); } if (rgbSignature == null) { throw new ArgumentNullException("rgbSignature"); } // Make sure that we have sufficient parameters to verify. if (dsaParams.G == null) { throw new CryptographicException (_("Crypto_DSAParamsNotSet")); } // Unpack the signature blob to get R and S. ASN1Parser parser; parser = (new ASN1Parser(rgbSignature)).GetSequence(); byte[] R = parser.GetBigInt(); byte[] S = parser.GetBigInt(); parser.AtEnd(); // Compute W = (S^-1 mod Q) byte[] W = CryptoMethods.NumInv(S, dsaParams.Q); // Compute U1 = ((hash * W) mod Q) byte[] U1 = CryptoMethods.NumMul(rgbHash, W, dsaParams.Q); // Compute U2 = ((R * W) mod Q) byte[] U2 = CryptoMethods.NumMul(R, W, dsaParams.Q); // Compute V = (((G^U1 * Y^U2) mod P) mod Q) byte[] temp1 = CryptoMethods.NumPow (dsaParams.G, U1, dsaParams.P); byte[] temp2 = CryptoMethods.NumPow (dsaParams.Y, U2, dsaParams.P); byte[] temp3 = CryptoMethods.NumMul(temp1, temp2, dsaParams.P); byte[] V = CryptoMethods.NumMod(temp3, dsaParams.Q); // Determine if we have a signature match. bool result = CryptoMethods.NumEq(V, R); // Clear sensitive values. Array.Clear(R, 0, R.Length); Array.Clear(S, 0, S.Length); Array.Clear(W, 0, W.Length); Array.Clear(U1, 0, U1.Length); Array.Clear(U2, 0, U2.Length); Array.Clear(temp1, 0, temp1.Length); Array.Clear(temp2, 0, temp2.Length); Array.Clear(temp3, 0, temp3.Length); Array.Clear(V, 0, V.Length); // Done. return(result); }
// Transform the final input block. public static byte[] TransformFinalBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount) { int blockSize = transform.blockSize; IntPtr state = transform.state; int offset = 0; int size, index, pad; byte[] outputBuffer; // Allocate space for the final block. if (transform.padding == PaddingMode.PKCS7) { size = inputCount + blockSize - (inputCount % blockSize); } else { size = inputCount; if ((size % blockSize) != 0) { size += blockSize - (inputCount % blockSize); } } outputBuffer = new byte [size]; // Process full blocks in the input. while (inputCount >= blockSize) { CryptoMethods.Encrypt(state, inputBuffer, inputOffset, outputBuffer, offset); inputOffset += blockSize; inputCount -= blockSize; offset += blockSize; } // Format and encrypt the final partial block. if (transform.padding == PaddingMode.PKCS7) { // Pad the block according to PKCS #7. for (index = 0; index < inputCount; ++index) { outputBuffer[offset + index] = inputBuffer[inputOffset + index]; } pad = blockSize - (inputCount % blockSize); while (index < blockSize) { outputBuffer[offset + index] = (byte)pad; ++index; } // Encrypt the block. CryptoMethods.Encrypt(state, outputBuffer, offset + index - blockSize, outputBuffer, offset + index - blockSize); } else if (inputCount > 0) { // Pad the block with zero bytes. for (index = 0; index < inputCount; ++index) { outputBuffer[offset + index] = inputBuffer[inputOffset + index]; } while (index < blockSize) { outputBuffer[offset + index] = (byte)0x00; ++index; } // Encrypt the block. CryptoMethods.Encrypt(state, outputBuffer, offset + index - blockSize, outputBuffer, offset + index - blockSize); } // Finished. return(outputBuffer); }
/// <summary> /// Remove a token /// </summary> /// <param name="refreshTokenId"></param> /// <returns></returns> public async Task RemoveTokenAsync(String refreshTokenId) { using (var transaction = await _context.Database.BeginTransactionAsync()) { var token = await _context.RefreshTokens.SingleOrDefaultAsync(o => o.TokenIdHash == CryptoMethods.GetSHA512Hash(refreshTokenId)); if (token != null) { _context.RefreshTokens.Remove(token); await _context.SaveChangesAsync(); transaction.Commit(); } } }
// Transform the final input block. public static byte[] TransformFinalBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount) { int blockSize = transform.blockSize; byte[] iv = transform.iv; IntPtr state = transform.state; int offset = 0; int size, pad, index; byte[] outputBuffer; // Allocate space for the final block. if (transform.padding == PaddingMode.PKCS7) { size = inputCount + blockSize - (inputCount % blockSize); } else { size = inputCount; if ((size % blockSize) != 0) { size += blockSize - (inputCount % blockSize); } } outputBuffer = new byte [size]; // Process full blocks in the input. while (inputCount >= blockSize) { // XOR the plaintext with the IV. for (index = blockSize - 1; index >= 0; --index) { iv[index] ^= inputBuffer[inputOffset + index]; } // Encrypt the IV to get the ciphertext and the next IV. CryptoMethods.Encrypt(state, iv, 0, iv, 0); Array.Copy(iv, 0, outputBuffer, offset, blockSize); // Advance to the next block. inputOffset += blockSize; inputCount -= blockSize; offset += blockSize; } // Format and encrypt the final partial block. if (transform.padding == PaddingMode.PKCS7) { // Pad the block according to PKCS #7 and XOR with the IV. for (index = 0; index < inputCount; ++index) { iv[index] ^= inputBuffer[inputOffset + index]; } pad = blockSize - (inputCount % blockSize); while (index < blockSize) { iv[index] ^= (byte)pad; ++index; } // Encrypt the IV to get the ciphertext and the next IV. CryptoMethods.Encrypt(state, iv, 0, iv, 0); Array.Copy(iv, 0, outputBuffer, offset, blockSize); } else if (inputCount > 0) { // Pad the block with zero bytes and XOR with the IV. // The zero padding is implicit. for (index = 0; index < inputCount; ++index) { iv[index] ^= inputBuffer[inputOffset + index]; } // Encrypt the IV to get the ciphertext and the next IV. CryptoMethods.Encrypt(state, iv, 0, iv, 0); Array.Copy(iv, 0, outputBuffer, offset, blockSize); } // Finished. return(outputBuffer); }
public void OpenSystemStore(StoreName store) { CryptoMethods.OpenSystemStore(store).IsInvalid.Should().BeFalse(); }
// Create a DSA signature for the specified data. public override byte[] CreateSignature(byte[] rgbHash) { // Validate the parameter. if (rgbHash == null) { throw new ArgumentNullException("rgbHash"); } // Check that we have sufficient DSA parameters to sign. if (dsaParams.G == null) { throw new CryptographicException (_("Crypto_DSAParamsNotSet")); } else if (dsaParams.X == null) { throw new CryptographicException (_("Crypto_CannotSignWithPublic")); } // Generate a random K less than Q to use in // signature generation. We guarantee less than // by setting the high byte of K to at least one // less than the high byte of Q. int len = dsaParams.Q.Length; byte[] K = new byte [len]; CryptoMethods.GenerateRandom(K, 1, K.Length - 1); int index = 0; while (index < len && K[index] >= dsaParams.Q[index]) { if (dsaParams.Q[index] == 0) { K[index] = (byte)0; ++index; } else { K[index] = (byte)(dsaParams.Q[index] - 1); break; } } // Compute R = ((G^K mod P) mod Q) byte[] temp1 = CryptoMethods.NumPow (dsaParams.G, K, dsaParams.P); byte[] R = CryptoMethods.NumMod(temp1, dsaParams.Q); Array.Clear(temp1, 0, temp1.Length); // Compute S = ((K^-1 * (hash + X * R)) mod Q) temp1 = CryptoMethods.NumInv(K, dsaParams.Q); byte[] temp2 = CryptoMethods.NumMul (dsaParams.X, R, dsaParams.Q); byte[] temp3 = CryptoMethods.NumAdd (rgbHash, temp2, dsaParams.Q); byte[] S = CryptoMethods.NumMul(temp1, temp3, dsaParams.Q); Array.Clear(temp1, 0, temp1.Length); Array.Clear(temp2, 0, temp2.Length); Array.Clear(temp3, 0, temp3.Length); Array.Clear(K, 0, K.Length); // Pack R and S into a signature blob and return it. ASN1Builder builder = new ASN1Builder(); builder.AddBigInt(R); builder.AddBigInt(S); byte[] sig = builder.ToByteArray(); Array.Clear(R, 0, R.Length); Array.Clear(S, 0, S.Length); return(sig); }
// Transform the final input block. public static byte[] TransformFinalBlock(CryptoAPITransform transform, byte[] inputBuffer, int inputOffset, int inputCount) { int blockSize = transform.blockSize; IntPtr state = transform.state; byte[] tempBuffer = transform.tempBuffer; byte[] outputBuffer; int offset, index, pad; // Allocate a temporary output buffer. outputBuffer = new byte [inputCount + blockSize]; // Push the remaining bytes through the decryptor. The // final block will end up in "transform.tempBuffer". offset = TransformBlock(transform, inputBuffer, inputOffset, inputCount, outputBuffer, 0); // Decrypt the final block in "tempBuffer". if (transform.tempSize > 0) { // Decrypt the ciphertext to get the plaintext. CryptoMethods.Decrypt(state, tempBuffer, 0, tempBuffer, 0); // Remove padding. if (transform.padding == PaddingMode.PKCS7) { // Use PKCS #7 padding. pad = tempBuffer[blockSize - 1]; if (pad == 0 || pad > blockSize) { pad = blockSize; } Array.Copy(tempBuffer, 0, outputBuffer, offset, blockSize - pad); offset += blockSize - pad; pad = 0; } else if (transform.padding == PaddingMode.Zeros) { // Strip zeroes from the end of the block. index = blockSize; while (index > 0 && tempBuffer[index - 1] == 0) { --index; } Array.Copy(tempBuffer, 0, outputBuffer, offset, index); offset += index; } else { // No padding, so return the whole block. Array.Copy(tempBuffer, 0, outputBuffer, offset, blockSize); offset += blockSize; } } // Reduce the output buffer size to the final length. if (offset != outputBuffer.Length) { byte[] newout = new byte [offset]; if (offset != 0) { Array.Copy(outputBuffer, 0, newout, 0, offset); } Array.Clear(outputBuffer, 0, outputBuffer.Length); outputBuffer = newout; } // Finished. return(outputBuffer); }