2017-10-17 49 views
0

我需要在C#中验证(而不是解密)在Symfony 2中创建的密码。在C#中验证symfony创建的密码

在C#中重写了在Symfony 2中构建的现有应用程序。安全令牌存储在本地数据库中。

当前Symfony的密码设置是

security: 
    encoders: 
     Symfony\Component\Security\Core\User\User: plaintext 
     API\CoreEntityBundle\Entity\User: 
      algorithm: sha512 
      iterations: 512 
      encode_as_base64: true 

我怎样才能可靠地散列给定的密码,并比较与存储的令牌,以确定是否提供的密码是正确的?

回答

1
  1. 如果您的密码被腌制:连接具有“{}盐”(故“EncodedPassword {} SaltUsed”是最后一个字符串),存储的密码salted。如果不是只存储salted的密码。使用
  2. 哈希salted SHA512,店digest
  3. 重复iterations - 1倍(511你的情况):
    • 串联digestsalted
    • 哈希级联使用SHA512,将结果存储在digest为下一次迭代
  4. Base64对最终的digest进行编码。

你也可以看看Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder的实现。

+0

您的意见帮助我找到了我发布的解决方案。非常重要的是你的笔记要执行(迭代-1)重复。 – crafter

0

这是一个工作版本。

string CalculateHash(string plain, string salt) 
     { 
      var salted = $"{plain}{{{salt}}}"; 

      var saltedBytes = Encoding.UTF8.GetBytes(salted); 

      using (var sha512 = SHA512.Create()) 
      { 
       var digest = sha512.ComputeHash(saltedBytes); 

       var outputBytes = new byte[digest.Length + saltedBytes.Length]; 

       for (var iteration = 1; iteration < 512; iteration++) 
       { 
        Buffer.BlockCopy(digest, 0, outputBytes, 0, digest.Length); 
        Buffer.BlockCopy(saltedBytes, 0, outputBytes, digest.Length, saltedBytes.Length); 

        digest = sha512.ComputeHash(outputBytes); 
       } 

       var result = Convert.ToBase64String(digest); 

       return result; 
      }