2016-12-23 49 views
3

心愛的RabbitMQ Management PluginHTTP API來通過純HTTP請求管理RabbitMQ。如何爲RabbitMQ管理HTTP API生成password_hash

我們需要以編程方式創建用戶,HTTP API是選擇的方式。文檔很少,但API非常簡單直觀。

關注安全性,我們不希望以純文本格式傳遞用戶密碼,而是提供一個字段來發送密碼散列。從那裏引用:

[GET | PUT | DELETE]/api/users/名稱

個別用戶。把一個用戶,您將需要一個身體尋找 是這樣的:

{"password":"secret","tags":"administrator"} 

或:

{"password_hash":"2lmoth8l4H0DViLaK9Fxi6l9ds8=", "tags":"administrator"} 

的標籤關鍵是強制性的。必須設置passwordpassword_hash

到目前爲止,這麼好,問題是:如何正確生成password_hash

password hashing algorithm配置在RabbitMQ的配置文件中,我們配置爲默認的SHA256。

我使用C#和下面的代碼生成散列:

var cr = new SHA256Managed(); 
var simplestPassword = "1"; 
var bytes = cr.ComputeHash(Encoding.UTF8.GetBytes(simplestPassword)); 
var sb = new StringBuilder(); 
foreach (var b in bytes) sb.Append(b.ToString("x2")); 
var hash = sb.ToString(); 

這是行不通的。在一些用於SHA256加密的在線工具中測試時,代碼正在生成預期的輸出。但是,如果我們轉到管理頁面並手動將用戶密碼設置爲「1」,那麼它就像一個魅力。

This answer導致我出口的配置和看看哈希的RabbitMQ正在生成,而且我意識到了一些東西:「1」的

  • 散列例如:「y4xPTRVfzXg68sz9ALqeQzARam3CwnGo53xS752cDV5 + Utzh」
  • 所有用戶的哈希都具有固定長度
  • 哈希每次都會更改(即使密碼相同)。我知道PB2K也是這樣做的密碼,但不知道這個加密屬性的名稱。
  • 如果我通過了password_hash的RabbitMQ的商店也沒有變化

我接受建議,另一種編程語言爲好,而不僅僅是C#。

+0

我相信他們散列沒有密碼,但加密的密碼。他們可能會使用一些RSA算法來獲取ecnrypted密碼,然後爲其計算散列值。 –

+0

爲了能夠生成散列,您需要查找用於加密密碼的密鑰。 –

+0

我試圖理解他們在源代碼中的作用(https://github.com/rabbitmq/rabbitmq-management/blob/master/src/rabbit_mgmt_wm_user.erl),但我對Erlang和函數式語言一無所知 – Dinei

回答

5

來源:http://rabbitmq.1065348.n5.nabble.com/Password-Hashing-td276.html

但是,如果你想實現它自己 的算法是相當簡單的。這裏的一個工作示例:

生成隨機的32位鹽:

CA D5 08 9B

連接之類的密碼(在此 情況下 「西蒙」)的UTF-8表示:

CA D5 08 73 9B 69 6D 6E 6F

採取MD5哈希:

CB 37 02 72 AC 08 5D E9 B6 99 17 4A 2B 5F 57 12

級聯這些再次鹽:

CA D5 08 9B CB 37 02 72 AC 5D 08 E9 B6 99 4A 17 2B 5F 57 12

,並轉換爲base64編碼:

ytUIm8s3AnKsXQjptplKFytfVxI =

你應該能夠修改代碼以遵循這個過程

+2

Thanks Derick ,它像一個魅力。對未來讀者的建議:它並不總是MD5,它取決於rabbitmq.config上配置的內容(自v3.6.0以來默認是SHA256) – Dinei

2

對於懶惰的人(和我一樣),有關於.Net核心的Sha512計算RabbitMq密碼的代碼。

public static class RabbitMqPasswordHelper 
{ 
    public static string EncodePassword(string password) 
    { 
     using (RandomNumberGenerator rand = RandomNumberGenerator.Create()) 
     using (var sha512 = SHA512.Create()) 
     { 
      byte[] salt = new byte[4]; 

      rand.GetBytes(salt); 

      byte[] saltedPassword = MergeByteArray(salt, Encoding.UTF8.GetBytes(password)); 
      byte[] saltedPasswordHash = sha512.ComputeHash(saltedPassword); 

      return Convert.ToBase64String(MergeByteArray(salt, saltedPasswordHash)); 
     } 
    } 

    private static byte[] MergeByteArray(byte[] array1, byte[] array2) 
    { 
     byte[] merge = new byte[array1.Length + array2.Length]; 
     array1.CopyTo(merge, 0); 
     array2.CopyTo(merge, array1.Length); 

     return merge; 
    } 
} 
+0

這節省了一些努力,謝謝:) –