2008-10-28 25 views
10

HMAC-SHA-256 karmaşasının temel bir testini kurmaya çalışıyorum ama motor kurulumunda sorun yaşıyorum. İdeal olarak sadece HMAC-SHA algoritmasını kurmak istiyorum ama şimdiye kadar bütün algoritmaların çalıştığı genel durumu bile almadım. Şu anda varsayılan sindirimleri ayarlamaya çalıştığım satırda segfaults alıyorum. Ayrıca, düzenli olarak bir Java kullanıcısıyım, bu nedenle koddaki herhangi bir hatayı işaret etmekte tereddüt etmeyin.OpenSSL'de motor başlatmayı anlama

#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() { 
    unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
    unsigned char* data = (unsigned char*) "4869205468657265"; 
    unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
    unsigned char* result; 
    HMAC_CTX* ctx; 
    ENGINE* e; 

    ENGINE_load_builtin_engines(); 
    ENGINE_register_all_complete(); 
    ENGINE_set_default_digests(e); 

    HMAC_CTX_init(ctx); 
    HMAC_Init_ex(ctx, key, 40, EVP_sha256(), e); 
    result = HMAC(NULL, NULL, 40, data, 16, NULL, NULL); 
    HMAC_CTX_cleanup(ctx); 

    ENGINE_finish(e); 
    ENGINE_free(e); 

    if (strcmp((char*) result, (char*) expected) == 0) { 
    printf("Test ok\n"); 
    } else { 
    printf("Got %s instead of %s\n", result, expected); 
    } 
} 

DÜZENLEME: Program şimdi, izleyen gelişti, ama yine de HMAC_Init_ex de segfaulting ediyorum:

unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
unsigned char* data = (unsigned char*) "4869205468657265"; 
unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
unsigned char* result; 
unsigned int result_len = 64; 
HMAC_CTX ctx; 
ENGINE* e; 

result = (unsigned char*) malloc(sizeof(char) * result_len); 
e = (ENGINE*) ENGINE_new(); 

ENGINE_load_builtin_engines(); 
ENGINE_register_all_complete(); 
ENGINE_set_default_digests(e); 

HMAC_CTX_init(&ctx); 
HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), e); 
HMAC_Update(&ctx, data, 40); 
HMAC_Final(&ctx, result, &result_len); 
HMAC_CTX_cleanup(&ctx); 

ENGINE_finish(e); 
ENGINE_free(e); 

cevap

13

Orijinal önerinizle ilgili sorun, Martin'in belirttiği gibi, MOTOR'ı başlatmanız gerektiğidir. Düzenlenmiş kodunuzla ilgili sorun, size tamamen yeni bir MOTOR almanızı sağlayan ENGINE_new'i gerçekleştirmenizdi. Bu, daha sonra şifreleme yöntemleri, özet yöntemleri, vb. Neredeyse herkesin istediği gibi, tüm ENGINE malzemelerini tamamen göz ardı etmek doğru seçimdir.

Bazı yan sorunlar:

  • Dizeleriniz altıgen, ama aslında ben ne istediğini oldu şüpheli dizede o pozisyonda, o altıgen byte almak için karakterin başına \ x gerekli.
  • "Veriler" den 40 baytlık bir hash elde etmeye çalışıyorsunuz, ki bu o kadar uzun olmayan bir gerçek değildi (gerçek etki: sonuç dizginizi kısmen bozuyordunuz)
  • Beklediğiniz sonucun) Hatalı
  • , HMAC işlevi, yazdırılabilir değil, 32 baytlık rastgele ikili veri üreteceğinden, rastgele karakterler yazdırırsınız.

Aşağıdaki kod sınama işlemini tamamlar, çalışır ve geçer. Tabii

#include <openssl/engine.h> 
#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 


int main(void) 
{ 
     unsigned char* key = (unsigned char*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; 
     unsigned char* data = (unsigned char*) "\x48\x69\x20\x54\x68\x65\x72\x65"; 
     unsigned char* expected = (unsigned char*) "\x49\x2c\xe0\x20\xfe\x25\x34\xa5\x78\x9d\xc3\x84\x88\x06\xc7\x8f\x4f\x67\x11\x39\x7f\x08\xe7\xe7\xa1\x2c\xa5\xa4\x48\x3c\x8a\xa6"; 
     unsigned char* result; 
     unsigned int result_len = 32; 
     int i; 
     HMAC_CTX ctx; 

     result = (unsigned char*) malloc(sizeof(char) * result_len); 

     ENGINE_load_builtin_engines(); 
     ENGINE_register_all_complete(); 

     HMAC_CTX_init(&ctx); 
     HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), NULL); 
     HMAC_Update(&ctx, data, 8); 
     HMAC_Final(&ctx, result, &result_len); 
     HMAC_CTX_cleanup(&ctx); 

     for (i=0; i!=result_len; i++) 
     { 
       if (expected[i]!=result[i]) 
       { 
         printf("Got %02X instead of %02X at byte %d!\n", result[i], expected[i], i); 
         break; 
       } 
     } 
     if (i==result_len) 
     { 
       printf("Test ok!\n"); 
     } 
     return 0; 
} 

, öyle değil: - Size (eğer biraz kullanarak HMAC_Update ederek karma düşeni yapmak istiyorsanız kullanışlı hala bireysel HMAC_ kullandığından * fonksiyonları) bulunan örnek koda biraz farklı MOTORLARIN nasıl başlatılacağı ile ilgili orijinal sorunuzu yanıtlayın, ancak daha fazla bağlamı olmayan, bu bağlamda sizin için uygun olan bir konuya doğru bir cevap yok ...

0
şey bir motor ayırdığından gibi gösteriyor

yüzden e ilk kullanımı segfaulting. İlk önce ENGINE *ENGINE_new(void) numaralı telefonu aramanız gerektiğini düşünüyorum.

(ı OpenSSL kullandım unutmayın, ama daha önce ENGINE işlevleri kullanmadım.)

Güncelleme: Kendi cevap gerçekten mutlu değilim (ben fırlayıp zorunda kaldı önce çay). Yani benim başka notlar:

  1. Ben ENGINE fonksiyonlar için (uzun) man page bir göz biraz aldık ve ben ENGINE_new arayarak yeterli olduğunu tam olarak emin değilim.

  2. HMAC_CTX_* işlevlerine yapılan çağrıların, ayrılan bir yapıya işaretçi değil, başlatılmamış bir işaretçi aldığını fark etmedim. HMAC_CTX_init, segfault yapacak olan ctx parametresiyle işaret edilen belleğe yazmaya çalışacaktır. Böyle beyan ve ctx kullanmak gerekir:

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 
    HMAC_Init_ex(&ctx, key, 40, EVP_sha256(), e); 
    ... 
    

    Bu şekilde buna bir işaretçi geçirmeden sonra yığın yapısını tahsis ve ediyoruz.

  3. HMAC fonksiyon global veya iş parçacığı yerel depolama yüzden ayrı, hiç bir CTX bir gösterici almaz, ben CTX bağlantı mi emin değilim. Bunu elde etmek için HMAC_Update tek veya daha fazla kez arayarak bunu HMAC_Final takip ederek geçebilirsiniz. O sonucun alan atamak gerekiyordu, bu yüzden aşağıdaki gibi bir şey olduğunu için de kullanılabilir:

    unsigned int len; 
    HMAC_Final(&ctx, result, &len); 
    
+0

Öneriniz için teşekkürler Martin, denedim Onları çıkardım ama hala sıkışıp kaldım. Bunu kullanmadığın hakkında MOTOR yorumunu merak ediyorum. OpenSSL'i motorsuz kullanmak mümkün mü? – Fylke

1

Tamam, bir motor kullanmak zorunda değilsiniz ama yanlış vermişti çıkıyor Tam olarak açık bir motor kullanmamak. Test vektörlerini doğru şekilde nasıl biçimlendireceğimi de yanlış anladım. Sonunda hmactest.c'ye baktım, ki tüm yapmak istediğim kadarını yaptım, sadece kodu anlamadım.

int main() { 
    unsigned char* key = (unsigned char*) "Jefe"; 
    unsigned char* data = (unsigned char*) "what do ya want for nothing?"; 
    unsigned char* expected = (unsigned char*) "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"; 
    unsigned char* result; 
    unsigned int result_len = 32; 
    int i; 
    static char res_hexstring[32]; 

    result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL); 
    for (i = 0; i < result_len; i++) { 
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]); 
    } 

    if (strcmp((char*) res_hexstring, (char*) expected) == 0) { 
    printf("Test ok, result length %d\n", result_len); 
    } else { 
    printf("Got %s instead of %s\n", res_hexstring, expected); 
    } 
} 

Ama tamamen farklı bir şey soruyordu beri, ben orijinal soru ile yapmanız gerekenler hakkında emin değilim:

benim yapmaya çalıştığım ne kadar son çözüm bu gibi görünüyor. Öneriler?

+0

NULL. Not: Statik diziyi kullanmak için md için bir NULL değeri iletmek iş parçacığı güvenli değildir. https://www.openssl.org/docs/man1.0.2/crypto/hmac.html – codenamezero