티스토리 툴바


(C#) MD5 hash

Programming 2014/04/17 23:19

http://blogs.msdn.com/b/csharpfaq/archive/2006/10/09/how-do-i-calculate-a-md5-hash-from-a-string_3f00_.aspx

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    class Program {
        public static string md5(string input) {
            // step 1, calculate MD5 hash from input
            var md5 = System.Security.Cryptography.MD5.Create();
            var inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            var hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            var sb = new StringBuilder();
            foreach (var b in hash) {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }

        static void Main(string[] args) {
            Console.WriteLine(md5("hello"));
            Console.ReadKey();
        }
    }
}

 

http://hilite.me/

Calculate MD5 checksum for a file

 

저작자 표시
Posted by steloflute

http://www.mimul.com/pebble/default/2013/02/18/1361189648941.html

 

최근 들어서 개인 정보 유출 등으로 인해 개인 정보 암호화 방법에 대해서 많이들 고민할 것입니다.
그 중에서 가장 중요하게 생각하는 것 중에 하나가 사용자의 패스워드인데, 과거에는 대부분 해시 MD5, SHA1 또는 SHA-256을 사용하고 있고, 좀 더 안다는 고급 개발자들이 있는 기업들만이 패스워드에 salt를 넣어 사용하고 있는 것으로 파악됩니다.(제가 잘못 알고 있을수도 있습니다.) 물론 최근들어 KISA의 제재로 salt + SHA1로 가는 추세이긴 합니다.
그러나 SHA1 + salt가 안전하다고 생각하는 분들은 아마 없을 듯 합니다. 그저 정부의 제재 수단을 회피하고자 적용하는 기업들이 많을 겁니다.

SHA1 + salt로 패스워드 보안 이슈 회피가 가능한가?

MD5, SHA1 또는 SHA-256 알고리즘은 보안이 우수하지 않다는 것은 다음 사이트에서 테스트해 보면 알 수 있습니다.
"http://google.com"을 MD5 인코딩한 값(c7b920f57e553df2bb68272f61570210)을 md5.rednoize.com 사이트에 넣고 검색 버튼을 클릭하면 바로 복호화되어 나옵니다.
md5.rednoize.com은 원본 데이터와 해시값의 데이터베이스를 참조해, 등록된 것은 즉시 해시값에서 데이터로 변환되어 출력하게 되는 구조입니다. 딕셔너리가 많이 확보되면 쉽게 패스워드를 풀 수 있게 된다는 소리도 됩니다.
이처럼 Rainbow Table("해시값이 이것이면, 암호는 이것"라는 테이블)을 사용해 일방향 암호화 기술을 무력화하게 됩니다. 이것만으로 보아도 일방향 암호화 알고리즘으로 MD5, SHA1 또는 SHA-256은 이제 한물간 일방향 암호화 알고리즘이라는 것을 쉽게 알 수 있죠.

그래서 보완책으로 나온 것이 SHA1 + salt입니다. salt를 붙이는 것으로, Rainbow Table 사용 접근 방식을 실질적으로 사용할 수 없게 하는 것으로 생각해 왔습니다.
SHA1 + salt의 처리방식은 아래와 같습니다.

$salt = "this is a salt";
$password = 'this is an password';
$hash = sha1($salt.$password);


자! 이 방법 또한 여기를 보듯이 GPU가 장착된 디바이스로 병렬처리하면 초당 수억건의 처리가 가능해 무력화 기술에 의해 무너질 수 있습니다. 이렇게 되면 딕셔너리 공격과 무력의 기술을 결합하여 많은 계정을 가진 대형 사이트에서도 상당한 양의 암호를 해독하는데, 그리 오랜 시간이 걸리지 않을 것입니다.

현재까지의 좀 더 강화된 방법으로는 뭐가 있을까요?

  • 각 사용자에게 고유 salt 값과 반복 횟수를 마련하는 것이고.
  • 좀 더 강력한 PBKDF2(http://en.wikipedia.org/wiki/PBKDF2), Bcrypt(http://www.openwall.com/crypt/), HMAC(http://en.wikipedia.org/wiki/HMAC)를 사용하는 것.
  • 불편하더라도 사용자에게 강한 강도의 패스워드를 받도록 유도하는 것.

정도가 될 것으로 보입니다.

PBKDF2 사용 샘플(Java)

public class PBKDF2 {

	//임의 salt를 생성
    private static byte[] createSalt() throws NoSuchAlgorithmException {
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        byte[] salt = new byte[32];
        random.nextBytes(salt);
        return salt;
    }

    private static byte[] pbkdf2(char[] password, byte[] salt) 
     throws InvalidKeySpecException, NoSuchAlgorithmException {
        SecretKeyFactory sf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        // 반복 횟수 : 10000 번 결과 길이 : 256bit
        KeySpec ks = new PBEKeySpec(password, salt, 10000, 256);
        SecretKey sk = sf.generateSecret(ks);
        return sk.getEncoded();
    }

    private static void logging(String format, Object ... args) {
        System.out.printf(format + "%n", args);
    }

    public static void main(String[] args) 
     throws NoSuchAlgorithmException, InvalidKeySpecException {
        String p1 = args[0];
        String p2 = args[1];
        logging("password 1= %s", p1);
        logging("password 2= %s", p2);

        byte[] salt = createSalt();
        logging("salt: %s", Arrays.toString(salt));

        byte[] d1 = pbkdf2(p1.toCharArray(), salt);
        byte[] d2 = pbkdf2(p2.toCharArray(), salt);
        logging("derived 1= %s", Arrays.toString(d1));
        logging("derived 2= %s", Arrays.toString(d2));
    }
}

위의 10000이라는 숫자가 반복횟수이므로 이를 증가시켜 안전성을 높일 수 있습니다. 이 수를 사용자별로 데이터베이스에 저장하여 두면 중간에 반복 횟수를 높이고 안전성을 향상시킬 수도 있습니다.

[참조사이트]

 

 

 

저작자 표시
Posted by steloflute
TAG IT
Parenj 1.8.1과 Paren# 0.2.1에서 간단하게 thread(쓰레드 생성)와 join(쓰레드 종료를 기다림)를 지원합니다.
 
 
예제:
> (set t1 (thread (for i 1 10 1 (pr "" i)))) (set t2 (thread (for j 11 20 1 (pr "" j)))) (join t1) (join t2)
1 11 2 12 3 4 5 136 7 8 9 1014 15 16 17 18 19 20 : null
 
요즘 느끼는 건.. "CPU가 변하면 프로그래밍 언어도 변해야 한다."입니다. 예전 C나 C++이 처음 나왔을 때는 컴퓨터 아키텍처 자체에 thread 개념이 없어서 thread를 라이브러리 형태로 사용하던 것이 C++11에서는 언어에 포함되었다고 합니다. 늦었지만 올바른 방향인 것 같습니다.
 
(pthread보다는 쓰기 쉬워 보이네요.) pthread 예제 | http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
 
p.s. Paren(C++버전)의 thread 지원은 준비중에 있습니다.

 

Update 2014-04-15

Paren(C++ 버전) 1.7.2에서 thread 지원

Paren | https://bitbucket.org/ktg/paren

 

 

저작자 표시
Posted by steloflute


Generate bitcoin for me

What's this?