2015-06-23 32 views
5

OpenSSL kullanarak Ubuntu makinemde bir mesaj imzalamak için SHA256 ve RSA kullanıyorum. Amacım Android'deki Java'yı kullanarak bu mesajı Android'de doğrulamaktır.OpenSSL kullanarak imzalanmış mesaj; Android Java ile doğrulayamıyor

ardından komutlar ubuntu üzerinde kullanılmıştır:

Şimdi anahtarlarını oluşturduk
openssl genrsa -out private.pem 1024 
openssl rsa -in private.pem -out public.pem -outform PEM -pubout 
echo 'foobar' > data.txt 
openssl dgst -sha256 <data.txt> hash 
openssl rsautl -sign -inkey private.pem -keyform PEM -in hash > signature 
openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der 
openssl enc -base64 -in signature -out base64_signature 

, mesaj imzalı Java erişilebilir gerekir kamu anahtar için bir .der dosyası oluşturulur ve mesaj kodlanmış Base64 ile. Daha sonra aygıtımdaki .der ortak anahtarını yerleştirin ve anahtarı PublicKey sınıfına başarıyla yükledim.

public static boolean verify(PublicKey publicKey,String data,String verification){ 
    java.security.Signature sig; 
    try { 
     sig = java.security.Signature.getInstance("SHA256WithRSA"); 
     sig.initVerify(publicKey); 
     try { 
      sig.update(verification.getBytes()); 
     } catch (Exception e) { 
      ... 
     } 

     if (!sig.verify(Base64.decode(data, Base64.DEFAULT))) { 
      return false; 
     } 
     return true; 
    } 
    catch .... 
    return false; 
} 

Parametreler yöntemini çağırarak:

Bu yöntem mesajı doğrulamak için kullanılır

verify(PublicKey, Base64 encoded data in a String that is to be verified, "foobar"); 

Açıkçası doğrulama başarısız olur ama nedenini anlayamıyorum. Sanırım kodlamayla (?) Bir şeyler yapmak zorunda.


Güncelleştirme! Base64.decode(data, Base64.DEFAULT)) sonuçlarını bir dosyaya yazmayı ve bir hexeditor kullanarak orijinal imza dosyasıyla karşılaştırmayı başardım. Tamamen farklı! Java, imzaları biraz farklı bir biçimde almayı ve üretmeyi umuyor ve üretmeyi umuyor.

+0

Metin kodlaması sorun olabilir. Bunu, kullanılan 'doğrulamanızın bir SAH256 MessageDigest'i oluşturarak ve çıktıyı OpenSSL hash ile karşılaştırarak kontrol edebilirsiniz. RSA/ECB/NoPadding ile Java'da şifresini çözerek imzanızın "içeriğini" de kontrol edebilirsiniz. – Robert

cevap

6

İletinin hashisi DER'de kodlanmalı, ardından PKCS # 1 ile doldurulmalı ve yalnızca özel anahtarla imzalanmalıdır. Ve Openssl bunun için bir komutu vardır (çünkü aslında standart bir prosedürdür). Bunun yerine

openssl dgst -sha256 <data.txt> hash 
openssl rsautl -sign -inkey private.pem -keyform PEM -in hash > signature 

size

openssl dgst -sha256 -binary -sign private.pem data.txt > signature 

do Ayrıca Not: Değişken

  • sig.update(verification.getBytes()) açıkça charset belirtmelidir String verification

    • data.txt bir satır başı karakteri içeren senin, bunu unutma - aynı karakter takımı, data.txt filini doldurmak için kullanıldı e, örneğin: sig.update(verification.getBytes("UTF-8"))

    Komutlarınızın/kodunuzun geri kalanı tamam görünüyor.


    UPD - farklar hakkında @GilCol cevap:

    doldurma mesajları imzalı ikisi için de aynıdır (PKCS # 1). Ama mesajlar farklı.

    Eğer openssl dgst -sha256 <data.txt> hash kullanmak

    , hash (openssl sürümüne bağlı olarak) içerecektir:

    (stdin)= aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f 
    

    veya

    aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f 
    

    Sadece düz metin ve size openssl rsautl -sign ... kullanarak imzalayacak mesajdır. Sonra ikili (saf) şeklinde karma almak ve openssl dgst -sha256 -binary <data.txt> hash kullanırsanız

    # raw message as-is - we can see the padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -raw -hexdump 
    0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff 00 61 ...............a # 
    00c0 - 65 63 30 37 30 36 34 35-66 65 35 33 65 65 33 62 ec070645fe53ee3b # 
    00d0 - 33 37 36 33 30 35 39 33-37 36 31 33 34 66 30 35 3763059376134f05 # your plain-text message 
    00e0 - 38 63 63 33 33 37 32 34-37 63 39 37 38 61 64 64 8cc337247c978add # 
    00f0 - 31 37 38 62 36 63 63 64-66 62 30 30 31 39 66 0a 178b6ccdfb0019f. # we can even see newline char (0a) at the end 
    
    # strip the padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -pkcs -hexdump 
    0000 - 61 65 63 30 37 30 36 34-35 66 65 35 33 65 65 33 aec070645fe53ee3 
    0010 - 62 33 37 36 33 30 35 39-33 37 36 31 33 34 66 30 b3763059376134f0 
    0020 - 35 38 63 63 33 33 37 32-34 37 63 39 37 38 61 64 58cc337247c978ad 
    0030 - 64 31 37 38 62 36 63 63-64 66 62 30 30 31 39 66 d178b6ccdfb0019f 
    0040 - 0a            . 
    

    doğru değil hala sonuç daha iyi olacaktır, imzalayın, ancak: Biz openssl rsautl -verify ... ile görebiliriz

    # raw message as-is - we can see the same padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -raw -hexdump 
    0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00d0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff 00 ................ 
    00e0 - ae c0 70 64 5f e5 3e e3-b3 76 30 59 37 61 34 f0 ..pd_.>..v0Y7a4. # the hash - now in binary form 
    00f0 - 58 cc 33 72 47 c9 78 ad-d1 78 b6 cc df b0 01 9f X.3rG.x..x...... # 
    
    # strip the padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -pkcs -hexdump 
    0000 - ae c0 70 64 5f e5 3e e3-b3 76 30 59 37 61 34 f0 ..pd_.>..v0Y7a4. # just the hash, nothing else 
    0010 - 58 cc 33 72 47 c9 78 ad-d1 78 b6 cc df b0 01 9f X.3rG.x..x...... # 
    

    Ancak, openssl dgst -sha256 -sign ...'u kullandığınızda, ileti farklıdır - artık ileti özetleri (karma) için standart bir ASN.1 yapısıdır. Bakalım: Gördüğünüz gibi, sadece son signature dosya düzgün ASN.1 yapıdır vardı

    # raw message as-is - we can see the same padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -raw -hexdump 
    0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 
    00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 31 30 .............010 # 
    00d0 - 0d 06 09 60 86 48 01 65-03 04 02 01 05 00 04 20 ...`.H.e....... # the message - it's different 
    00e0 - ae c0 70 64 5f e5 3e e3-b3 76 30 59 37 61 34 f0 ..pd_.>..v0Y7a4. # <- we can see the hash (in binary form) starting at this line 
    00f0 - 58 cc 33 72 47 c9 78 ad-d1 78 b6 cc df b0 01 9f X.3rG.x..x...... # 
    
    # strip the padding 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -pkcs -hexdump 
    0000 - 30 31 30 0d 06 09 60 86-48 01 65 03 04 02 01 05 010...`.H.e..... 
    0010 - 00 04 20 ae c0 70 64 5f-e5 3e e3 b3 76 30 59 37 .. ..pd_.>..v0Y7 
    0020 - 61 34 f0 58 cc 33 72 47-c9 78 ad d1 78 b6 cc df a4.X.3rG.x..x... 
    0030 - b0 01 9f           ... 
    
    # parse the message and show the underlying ASN.1 structure 
    $ openssl rsautl -in signature -pubin -inkey public.pem -verify -pkcs -asn1parse 
        0:d=0 hl=2 l= 49 cons: SEQUENCE   
        2:d=1 hl=2 l= 13 cons: SEQUENCE   
        4:d=2 hl=2 l= 9 prim: OBJECT   :sha256    # type of hash 
        15:d=2 hl=2 l= 0 prim: NULL    
        17:d=1 hl=2 l= 32 prim: OCTET STRING  
         0000 - ae c0 70 64 5f e5 3e e3-b3 76 30 59 37 61 34 f0 ..pd_.>..v0Y7a4. # the hash in binary form 
         0010 - 58 cc 33 72 47 c9 78 ad-d1 78 b6 cc df b0 01 9f X.3rG.x..x...... # and no extra newline chars 
    

    , önceki iki vardı sadece RSA özel anahtarla imzalanmış "bazı keyfi" iletiler.

  • +0

    Teşekkürler, sorunumu çözdü. Ayrıca bu konuyu buldum: http://stackoverflow.com/questions/13419201/why-are-the-rsa-sha256-signatures-i-generate-with-openssl-and-java-different Ama yine de yapmam Bu komutlar arasındaki kriptografik farkı anlar. Dolgu farklı mı, ne? – GilCol

    +0

    @GilCol Cevabımı güncelledim. – Roman

    +0

    Hayatımı bu açıklama ile kurtardın, teşekkürler! – GregaMohorko