2012-03-13 5 views
1

저는 Windows 및 Linux 용 Vala에 크로스 플랫폼 응용 프로그램을 작성하고 있습니다. 보안을 위해 Hmac을 구현해야합니다. 하지만 불행히도 GHmac 클래스 (link)는 아직 Windows에 이식되지 않았습니다. 나는 위키 피 디아 (link)에서 Hmac의 알고리즘을 발견했다. 나는 올바르게 구현했다고 믿지만, 내장 된 클래스와 비교할 때 나는 같은 결과를 얻지 못한다. 누군가 내게 놀라운 버그를 찾는 손을 줄 수 있다면 아래에 내 기능이 있습니다.Vala에 Hmac 함수 작성

public static string compute_for_data(ChecksumType type, uint8[] key, 
                  uint8[] data) { 
    int block_size = 64; 
    uint8[] mod_key = key; 
    uint8[] outer = new uint8[block_size]; 
    uint8[] inner = new uint8[block_size]; 

    if (mod_key.length > block_size) { 
     mod_key = Checksum.compute_for_data(type, key).data; 
    } 
    mod_key.resize(block_size); 

    for (int i=0; i < mod_key.length; i++) { 
     outer[i] = mod_key[i]^0x5c; 
     inner[i] = mod_key[i]^0x36; 
    } 

    int i = inner.length; 
    inner.resize(i + data.length); 
    for (int j=0; j < data.length; j++) { 
     inner[i + j] = data[j]; 
    } 

    inner = Checksum.compute_for_data(type, inner).data; 

    i = outer.length; 
    outer.resize(i + inner.length); 
    for (int j=0; j < inner.length; j++) { 
     outer[i + j] = inner[j]; 
    } 

    return Checksum.compute_for_data(type, outer); 
} 

답변

2

나는 그 자신의 질문에 대답하기에는 그 끈적 함을 안다. 그러나 나는 친구의 도움으로 그 문제를 해결할 수 있었다. 그래서 여기에 해결책이있다. 기본적으로 Checksum.compute_for_data 함수를 사용하면 16 진수가 아닌 16 진수 문자열이 반환되고 알고리즘이 깨졌습니다. 다음은 수정 된 버전입니다.

public static string compute_for_data(ChecksumType type, uint8[] key, 
                  uint8[] data) { 
    int block_size = 64; 
    switch (type) { 
     case ChecksumType.MD5: 
     case ChecksumType.SHA1: 
      block_size = 64; /* RFC 2104 */ 
      break; 
     case ChecksumType.SHA256: 
      block_size = 64; /* RFC draft-kelly-ipsec-ciph-sha2-01 */ 
      break; 
    } 

    uint8[] buffer = key; 
    if (key.length > block_size) { 
     buffer = Checksum.compute_for_data(type, key).data; 
    } 
    buffer.resize(block_size); 

    Checksum inner = new Checksum(type); 
    Checksum outer = new Checksum(type); 

    uint8[] padding = new uint8[block_size]; 
    for (int i=0; i < block_size; i++) { 
     padding[i] = 0x36^buffer[i]; 
    } 
    inner.update(padding, padding.length); 
    for (int i=0; i < block_size; i++) { 
     padding[i] = 0x5c^buffer[i]; 
    } 
    outer.update(padding, padding.length); 

    size_t length = buffer.length; 
    inner.update(data, data.length); 
    inner.get_digest(buffer, ref length); 

    outer.update(buffer, length); 
    return outer.get_string(); 
}