md5_crypt




C#版。相変わらずnamespaceは適当。http://d.hatena.ne.jp/maruguu/20050122#p1と組み合わせて使用。

using System;
using System.Text;

namespace Utility
{
public class crypt
{
// saltは8文字以下
public static string md5_crypt(string pw, string salt)
{
string magic = "$1$";
byte[] pw_bytes = Encoding.ASCII.GetBytes(pw);
byte[] salt_bytes = Encoding.ASCII.GetBytes(salt);
byte[] magic_bytes = Encoding.ASCII.GetBytes(magic);
MD5 md5 = new MD5();
int p_len = pw.Length;

md5.init();
md5.update(pw_bytes, pw_bytes.Length);
md5.update(salt_bytes, salt_bytes.Length);
md5.update(pw_bytes, pw_bytes.Length);
md5.finalize();
byte[] M1 = md5.digest;

md5.init();
md5.update(pw_bytes, pw_bytes.Length);
md5.update(magic_bytes, magic_bytes.Length);
md5.update(salt_bytes, salt_bytes.Length);
for(int i = p_len; i > 0; i -= 16)
if(i > 16)
md5.update(M1, 16);
else
md5.update(M1, i);
byte[] alt = new byte[1];
alt[0] = (byte)'\0';
for (int i = p_len; i != 0 ; i >>= 1)
{
if((i & 1) != 0)
md5.update(alt, 1);
else
md5.update(pw_bytes, 1);
}
md5.finalize();
byte[] M2 = md5.digest;

byte[] M3 = M2;
for(int i = 0; i < 1000; i++)
{
md5.init();
if((i & 1) != 0)
md5.update(pw_bytes, pw_bytes.Length);
else
md5.update(M3, 16);

if(i % 3 != 0)
md5.update(salt_bytes, salt_bytes.Length);
if(i % 7 != 0)
md5.update(pw_bytes, pw_bytes.Length);

if((i & 1) != 0)
md5.update(M3, 16);
else
md5.update(pw_bytes, pw_bytes.Length);
md5.finalize();
M3 = md5.digest;
}

string result = magic + salt + "$";
ulong l;
l = (ulong)((M3[ 0]<<16) | (M3[ 6]<<8) | M3[12]); result += to64(l,4);
l = (ulong)((M3[ 1]<<16) | (M3[ 7]<<8) | M3[13]); result += to64(l,4);
l = (ulong)((M3[ 2]<<16) | (M3[ 8]<<8) | M3[14]); result += to64(l,4);
l = (ulong)((M3[ 3]<<16) | (M3[ 9]<<8) | M3[15]); result += to64(l,4);
l = (ulong)((M3[ 4]<<16) | (M3[10]<<8) | M3[ 5]); result += to64(l,4);
l =                         M3[11]              ; result += to64(l,2);
return result;
}

// n < 5
private static string to64(ulong bits, uint n)
{
string b64t = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string result = "";
for(int i = 0; i < n; i++)
result += b64t[ (int)((bits >> (i * 6))) & 0x3f ];
return result;
}
}
}



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です