- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 .Net framework 4.5 中的 api,它应该为我提供加密货币钱包。在它的一部分 documentations它说:
Pass Pin Code through the PBKDF2 function with 128 Bit Key Length and 1,024 iterations of SHA256
我找不到 C# 中的 Specify 方法来执行此操作。在文档中,他们输入了“be9d3a4f1220495a96c38d36d8558365”作为 pin 码,输出为“4369cb0560d54f55d0c03564fbd983c4”。看来我应该使用 Rfc2898DeriveBytes 方法,我像下面的代码一样使用它,但没有得到相同的结果。
string output = Convert.ToBase64String((new Rfc2898DeriveBytes("e24546d6643137a310968566cf1cd42b",16, 1024)).GetBytes(32));
输出 ==> 'x10zclBJY2eeZqjMyPfQm4ljyMFPvWbxF72Om2DCzHE='
最佳答案
最好实现您自己的 PBKDF2 版本。 PBKDF2 是由错误命名的 Rfc2898DeriveBytes 类实现的实际算法。
因为 .NET 4.5 不包含使用具有不同哈希的 PBKDF2 的功能。 .NET 版本 4.7.2 确实包含该功能,但它不允许 salt 为零字节。
因此最好实现自己的版本。 Microsoft 的 .NET 版本具有似乎不兼容的特定版权声明。解决这个问题的一种方法是从 Mono 实现 PBKDF2,但是 Mono 的更高版本没有实现这个类(看起来)并且它们没有实现可以选择散列的版本。
幸运的是bartonjs has indicated a version具有许可的 MIT 许可,可以使用,导致以下解决方案:
using System;
using System.Security.Cryptography;
using System.Text;
namespace StackOverflow
{
public class Rfc2898DeriveBytes : DeriveBytes
{
private const string DEFAULT_HASH_ALGORITHM = "SHA-1";
private const int MinimumSaltSize = 0;
private readonly byte[] _password;
private byte[] _salt;
private uint _iterations;
private HMAC _hmac;
private int _blockSize;
private byte[] _buffer;
private uint _block;
private int _startIndex;
private int _endIndex;
public string HashAlgorithm { get; }
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations)
: this(password, salt, iterations, DEFAULT_HASH_ALGORITHM)
{
}
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, string hashAlgorithm)
{
if (salt == null)
throw new ArgumentNullException(nameof(salt));
if (salt.Length < MinimumSaltSize)
throw new ArgumentException(nameof(salt));
if (iterations <= 0)
throw new ArgumentOutOfRangeException(nameof(iterations));
if (password == null)
throw new NullReferenceException(); // This "should" be ArgumentNullException but for compat, we throw NullReferenceException.
_salt = (byte[])salt.Clone();
_iterations = (uint)iterations;
_password = (byte[])password.Clone();
HashAlgorithm = hashAlgorithm;
_hmac = OpenHmac();
// _blockSize is in bytes, HashSize is in bits.
_blockSize = _hmac.HashSize >> 3;
Initialize();
}
public Rfc2898DeriveBytes(string password, byte[] salt)
: this(password, salt, 1000)
{
}
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations)
: this(password, salt, iterations, DEFAULT_HASH_ALGORITHM)
{
}
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations, string hashAlgorithm)
: this(Encoding.UTF8.GetBytes(password), salt, iterations, hashAlgorithm)
{
}
public Rfc2898DeriveBytes(string password, int saltSize)
: this(password, saltSize, 1000)
{
}
public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
: this(password, saltSize, iterations, DEFAULT_HASH_ALGORITHM)
{
}
public Rfc2898DeriveBytes(string password, int saltSize, int iterations, string hashAlgorithm)
{
if (saltSize < 0)
throw new ArgumentOutOfRangeException(nameof(saltSize));
if (saltSize < MinimumSaltSize)
throw new ArgumentException(nameof(saltSize));
if (iterations <= 0)
throw new ArgumentOutOfRangeException(nameof(iterations));
_salt = new byte[saltSize];
RandomNumberGenerator.Create().GetBytes(_salt);
_iterations = (uint)iterations;
_password = Encoding.UTF8.GetBytes(password);
HashAlgorithm = hashAlgorithm;
_hmac = OpenHmac();
// _blockSize is in bytes, HashSize is in bits.
_blockSize = _hmac.HashSize >> 3;
Initialize();
}
public int IterationCount
{
get
{
return (int)_iterations;
}
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException(nameof(value));
_iterations = (uint)value;
Initialize();
}
}
public byte[] Salt
{
get
{
return (byte[])_salt.Clone();
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (value.Length < MinimumSaltSize)
throw new ArgumentException("Too few bytes for salt");
_salt = (byte[])value.Clone();
Initialize();
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_hmac != null)
{
_hmac.Dispose();
_hmac = null;
}
if (_buffer != null)
Array.Clear(_buffer, 0, _buffer.Length);
if (_password != null)
Array.Clear(_password, 0, _password.Length);
if (_salt != null)
Array.Clear(_salt, 0, _salt.Length);
}
base.Dispose(disposing);
}
public override byte[] GetBytes(int cb)
{
if (cb <= 0)
throw new ArgumentOutOfRangeException(nameof(cb));
byte[] password = new byte[cb];
int offset = 0;
int size = _endIndex - _startIndex;
if (size > 0)
{
if (cb >= size)
{
Buffer.BlockCopy(_buffer, _startIndex, password, 0, size);
_startIndex = _endIndex = 0;
offset += size;
}
else
{
Buffer.BlockCopy(_buffer, _startIndex, password, 0, cb);
_startIndex += cb;
return password;
}
}
while (offset < cb)
{
byte[] T_block = Func();
int remainder = cb - offset;
if (remainder > _blockSize)
{
Buffer.BlockCopy(T_block, 0, password, offset, _blockSize);
offset += _blockSize;
}
else
{
Buffer.BlockCopy(T_block, 0, password, offset, remainder);
offset += remainder;
Buffer.BlockCopy(T_block, remainder, _buffer, _startIndex, _blockSize - remainder);
_endIndex += (_blockSize - remainder);
return password;
}
}
return password;
}
public byte[] CryptDeriveKey(string algname, string alghashname, int keySize, byte[] rgbIV)
{
// If this were to be implemented here, CAPI would need to be used (not CNG) because of
// unfortunate differences between the two. Using CNG would break compatibility. Since this
// assembly currently doesn't use CAPI it would require non-trivial additions.
// In addition, if implemented here, only Windows would be supported as it is intended as
// a thin wrapper over the corresponding native API.
// Note that this method is implemented in PasswordDeriveBytes (in the Csp assembly) using CAPI.
throw new PlatformNotSupportedException();
}
public override void Reset()
{
Initialize();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "HMACSHA1 is needed for compat. (https://github.com/dotnet/corefx/issues/9438)")]
private HMAC OpenHmac()
{
String hashAlgorithm = HashAlgorithm;
if (string.IsNullOrEmpty(hashAlgorithm))
throw new CryptographicException("HashAlgorithm name not present");
if (hashAlgorithm.Equals("SHA-1", StringComparison.OrdinalIgnoreCase))
return new HMACSHA1(_password);
if (hashAlgorithm.Equals("SHA-256", StringComparison.OrdinalIgnoreCase))
return new HMACSHA256(_password);
if (hashAlgorithm.Equals("SHA-384", StringComparison.OrdinalIgnoreCase))
return new HMACSHA384(_password);
if (hashAlgorithm.Equals("SHA-512", StringComparison.OrdinalIgnoreCase))
return new HMACSHA512(_password);
throw new CryptographicException("MAC algorithm " + hashAlgorithm + " not available");
}
private void Initialize()
{
if (_buffer != null)
Array.Clear(_buffer, 0, _buffer.Length);
_buffer = new byte[_blockSize];
_block = 1;
_startIndex = _endIndex = 0;
}
// This function is defined as follows:
// Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i)
// where i is the block number.
private byte[] Func()
{
byte[] temp = new byte[_salt.Length + sizeof(uint)];
Buffer.BlockCopy(_salt, 0, temp, 0, _salt.Length);
WriteInt(_block, temp, _salt.Length);
temp = _hmac.ComputeHash(temp);
byte[] ret = temp;
for (int i = 2; i <= _iterations; i++)
{
temp = _hmac.ComputeHash(temp);
for (int j = 0; j < _blockSize; j++)
{
ret[j] ^= temp[j];
}
}
// increment the block count.
_block++;
return ret;
}
private void WriteInt(uint i, byte[] buf, int bufOff)
{
buf[bufOff++] = (byte)(i >> 24);
buf[bufOff++] = (byte)(i >> 16);
buf[bufOff++] = (byte)(i >> 8);
buf[bufOff] = (byte)i;
}
}
}
这是一个类,其中更具体的异常已被重写,一些专门的克隆被替换,随机盐生成被推广。最小盐大小也已设置为 0。否则它是不同 namespace 中的相同代码。
可以这样使用:
string pw = "be9d3a4f1220495a96c38d36d8558365";
byte[] salt = new byte[0];
int iterations = 1024;
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(pw, salt, iterations, "SHA-256");
byte[] key = pbkdf2.GetBytes(16);
请注意,PIN 是十六进制编码为 UTF-8,这是 PBKDF2 的默认编码(不是 .NET 的默认编码!)。结果是一个 key ,当以十六进制表示时等于 4369cb0560d54f55d0c03564fbd983c4
。
我已经使用字符串转换为 4.5 兼容类来指示哈希函数,对于带有枚举 HashAlgorithm
(4.6 或类似的东西)的类,请查看 the revision history .
关于c# - .Net Framework 4.5 中具有 128 位 key 长度和 1,024 次 SHA256 迭代的 PBKDF2 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53228398/
安全服务 API 似乎不允许我直接计算哈希。有很多公共(public)领域和自由许可的版本可用,但如果可能的话,我宁愿使用系统库实现。 可以通过 NSData 或普通指针访问数据。 哈希的加密强度对我
我有一堆大对象,以及它们的结构和它们的向量。有时检查复合对象的完整性很重要;为此,我正在使用对象的 Sha256“签名”。 至少有两种方法可以定义复合对象的签名:通过计算组件串联的sha,或者通过计算
研究了一个 cpu 矿工的源代码,我发现了这段代码: work->data[20] = 0x80000000; 好吧,我问了编码,他的回答是: “这些值是标准 SHA-2 填充的一部分” 谷歌搜索“s
您是否需要许可证才能将 SHA-1 或 SHA-2 用于商业目的? 最佳答案 它最初由 NSA 为安全 DSA 加密创建,然后被 NIST 采用以维护算法的所有方面以及 SHA(2 和 3)。 这是一
谁能解释一下 SHA-256 和 RIPEMD-160,哪种算法通常更快,性能和空间比较是什么(如果有)?我所说的空间比较并不是指 160 位和 256 位,而是指冲突频率、生产环境中空间要求的差异。
我对 SHA-2 和 SHA-256 之间的区别有点困惑,并且经常听到它们互换使用。我认为 SHA-2 是哈希算法的“家族”,而 SHA-256 是该家族中的特定算法。任何人都可以消除困惑。 最佳答案
我正在尝试从 SHA-1 更改为 SHA-512 以获得更好的安全性,但我不完全清楚如何进行更改。 这是我使用 SHA-1 的方法: public static String sha1Convert(
在我的 C# 应用程序中,我使用 RSA 对文件进行签名,然后再由上传者上传到我公司的数据库中,在这里我必须选择 SHA-1 或 SHA-2 来计算哈希值。与编程中的任何其他组件一样,我知道必须有一个
我正在研究 SHA1 、 SHA-256 、 SHA-512 在不同处理器上的速度(计算哈希的时间) 这些散列算法可以分解为跨多个核心/线程运行吗? 最佳答案 如果您想将计算单个哈希的执行并行化(无论
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 9年前关闭。 Improve this que
这个问题在这里已经有了答案: SHA2 password hashing in java (4 个答案) 关闭 9 年前。 我需要计算文件的 SHA-2 或 SHA-3。我没有提交任何代码示例来说明
在我的应用中,之前开发者已经使用openssl version 1.0.1e [#include openssl/sha.h]并且已经使用了函数 unsigned char *SHA(const un
我正在尝试实现 SHA-2加密而不是 SHA-1 . 为此,我知道这两种哈希算法之间的位数不同,这让我很困惑。 如何实现这一目标以及我需要在哪些部分进行必要的更改? 我可以使用来自 Java、Pyth
我目前正在使用 SHA-1。我像下面的代码一样使用它,但我想将它更改为 SHA-256。 public String sha1Encrypt(String str) { if(str == nul
我想将一些 Java 代码转换为 C#。 Java 代码: private static final byte[] SALT = "NJui8*&N823bVvy03^4N".getBytes()
我的程序使用 SHA-1 证书进行 SSL 连接。 SHA-2 证书现在已被一些网络服务(Gmail)广泛使用。这会导致在电子邮件通知设置期间阻止与 SMTP 服务器的传入连接。 为了发送电子邮件,我
我在提交中生成差异/更改,以便我可以将其上传到 ReviewBoard。 我使用了“git show d9f7121e8ebd4d1f789dab9f8214ada2h480b9cf”。它给了我 di
我刚刚从这个 HN-post 了解到 git 正在转向新的散列算法(从 SHA-1 到 SHA-256 ) 我想知道是什么让 SHA-256 最适合 git 的用例。 是否有任何/许多强有力的技术原因
是的,我需要降级到 SHA-1 以增加对项目中旧浏览器的兼容性。 有没有办法做到这一点? 我正在使用 Linux Centos 6.5 和 Apache/2.2.15。 我有 3 个文件: SSLCe
在 TLS1.1 和 TLS1.2 中,Cipher(rsa-with-aes-128-cbc-sha) 将使用哪个 Digest(SHA1 或 SHA256)? 最佳答案 根据官方openssl w
我是一名优秀的程序员,十分优秀!