Prehash ve SignPrehash temel işlevleri, dijital imza hesaplamasını iki adıma böler:
- Prehash için yalnızca ortak anahtar gerekir. İstediğiniz uzunluktaki bir mesajı kısa ve sabit boyutlu bir ön karma değerine dönüştürür.
- SignPrehash için özel anahtar gerekir. Önceden karma oluşturulmuş bir değeri imzaya dönüştürür.
Ortaya çıkan imza, orijinal mesajın üzerindeki normal bir imzadır. Bunu normal dijital imza PublicKeyVerify öğesiyle doğruladığınızda doğrulayıcıların, imzanın iki adımda oluşturulduğunu bilmesi veya bununla ilgilenmesi gerekmez.
Önceden karma oluşturulmuş değeri opak baytlar olarak ele alın. Sabit bir boyutu vardır ve hesaplandığı anahtarın kimliğini taşır. Ancak düzeni Tink'in kablo biçiminin bir parçasıdır ve kendiniz ayrıştırmamalı veya oluşturmamalısınız. Tink'i taşıyorsanız veya bayt düzeyindeki ayrıntılara ihtiyacınız varsa Tink wire format başlıklı makaleyi inceleyin.
Bu temel öğe çiftini şu durumlarda kullanın:
- İmzalama anahtarı başka bir yerde (ör. HSM, KMS veya RPC sınırı arkasında) bulunuyor ve tam mesajı bu sınırın ötesine göndermek istemiyorsunuz.
- İleti büyük ve uzaktan imzalayan, istek boyutu sınırı uyguluyor.
Bu iki durumdan hiçbiri geçerli değilse bunun yerine basit Digital Signature (Dijital İmza) öğesini kullanın. Bu öğe daha basittir ve kötüye kullanılması daha zordur.
Anahtar kümeleri
İki temel işlem, anahtarları farklı şekilde seçer. Bu durum, imzalama ve doğrulamanın dijital imza temel işleminde yaptığıyla aynıdır:
Prehash.Computeher zaman ortak anahtar kümesinin birincil anahtarını kullanır ve bu anahtarın kimliğini karma öncesi değerine kaydeder. İmzanın hangi anahtarla oluşturulacağını seçen taraftır.SignPrehash.Sign, anahtar kimliğini ön karma değerinden okur ve özel anahtar kümesinin eşleşen etkin anahtarıyla imzalar. Bu taraf, başka birinin daha önce yaptığı bir seçimi takip eder. Anahtar kümesinde bu kimliğe sahip etkin bir anahtar yoksa çağrı başarısız olur.
SignPrehash anahtar kümesindeki her anahtarın bir kimlik koşulu olmalıdır. Aksi takdirde, temel öğe oluşturma işlemi başarısız olur.
Minimum güvenlik garantileri
- Elde edilen imza, aynı anahtar türüyle Digital Signature (Dijital İmza) öğesi tarafından oluşturulan imza ile aynı özelliklere sahiptir.
- Tink, ön karma değerine özel ayrılmış bir değer ve hesaplandığı anahtarın kimliğini içeren 5 baytlık bir önek ekler.
SignPrehashyalnızca bu anahtarla değeri imzalar. Değerin bu anahtara kriptografik olarak bağlı olup olmadığı algoritmaya bağlıdır. External Mu ML-DSA için bu durum geçerlidir. Tink wire format'a bakın. - Mesajlar herhangi bir uzunlukta olabilir.
Dikkat etmeniz gerekenler
- İmzalayan kişi, imzaladığı şeyi inceleyemez.
SignPrehashkullanıcısını arayabilen herkes rastgele bir mesajı imzalatabilir ve imzalayan, mesaj içeriklerine politika uygulayamaz.SignPrehashhizmetine erişimi,PublicKeySignhizmetine erişimi koruduğunuz şekilde koruyun. - Geçiş hâlindeki ön karma değerini koruyun. Gizli değildir ancak iletim sırasında bunu değiştirebilen bir saldırgan, neyin imzalanacağını kontrol eder.
Anahtar türü seçin
RFC 9881'de açıklandığı gibi, External Mu modundaki ML-DSA, Tink'in Prehash ve SignPrehash için desteklediği tek algoritmadır. Bu temel öğelerle birlikte standart bir ML-DSA anahtarı kullanmanız gerekir.
Çoğu kullanım alanı için ML_DSA_65'i kullanmanızı öneririz.
Her ön karma değeri, hesaplandığı anahtarın kimliğini içeren bir önekle başladığından anahtarın kimlik koşulu olmalıdır. Aşağıdaki varyantlar kabul edilir:
TINK-- Sonuçta ortaya çıkan imza, Tink'in normal 5 baytlık çıkış ön ekiyle başlar.NO_PREFIX_WITH_PREHASH_ID: Sonuçta elde edilen imza, çıktı öneki içermez. Anahtar ise karma oluşturma öncesi değerin ihtiyaç duyduğu kimliğe sahiptir.
NO_PREFIX (ham) varyantını kullanan anahtarlar, anahtar kimliği içermediğinden desteklenmez.
Örnekler
Aşağıdaki örneklerde, bir ileti iki adımda imzalanır ve sonuçtaki imza, normal dijital imza öğesiyle doğrulanır.
Okunabilirlik için tek bir blok olarak gösterilir. Gerçek bir dağıtımda iki adım farklı yerlerde çalışır. Adım adım açıklama için Verileri uzaktan imzalayan bir kişiyle imzalamak istiyorum başlıklı makaleyi inceleyin.
C++
#include "tink/keyset_handle.h" #include "tink/public_key_verify.h" #include "tink/signature/config_2026.h" #include "tink/signature/prehash.h" #include "tink/signature/sign_prehash.h" using ::crypto::tink::ConfigSignature2026; using ::crypto::tink::Prehash; using ::crypto::tink::PublicKeyVerify; using ::crypto::tink::SignPrehash; // 1. Wherever the message is: compute the prehash value. This needs only // the public keyset. absl::StatusOr<std::unique_ptr<Prehash>> prehasher = public_handle.GetPrimitive<Prehash>(ConfigSignature2026()); if (!prehasher.ok()) return prehasher.status(); absl::StatusOr<std::string> prehash = (*prehasher)->Compute(message); if (!prehash.ok()) return prehash.status(); // 2. Wherever the private key is: turn the prehash value into a signature. absl::StatusOr<std::unique_ptr<SignPrehash>> signer = private_handle.GetPrimitive<SignPrehash>(ConfigSignature2026()); if (!signer.ok()) return signer.status(); absl::StatusOr<std::string> signature = (*signer)->Sign(*prehash); if (!signature.ok()) return signature.status(); // 3. Anywhere: verify the signature over the original message. absl::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier = public_handle.GetPrimitive<PublicKeyVerify>(ConfigSignature2026()); if (!verifier.ok()) return verifier.status(); absl::Status verified = (*verifier)->Verify(*signature, message);
Go
import ( "github.com/tink-crypto/tink-go/v2/signature" "github.com/tink-crypto/tink-go/v2/signprehash" ) // 1. Wherever the message is: compute the prehash value. This needs only // the public keyset. prehasher, err := signprehash.NewPrehash(publicHandle) if err != nil { return err } prehash, err := prehasher.ComputePrehash(message) if err != nil { return err } // 2. Wherever the private key is: turn the prehash value into a signature. signer, err := signprehash.NewPrehashSigner(privateHandle) if err != nil { return err } sig, err := signer.SignPrehash(prehash) if err != nil { return err } // 3. Anywhere: verify the signature over the original message. verifier, err := signature.NewVerifier(publicHandle) if err != nil { return err } if err := verifier.Verify(sig, message); err != nil { return err }
İlgili konular
- Verileri uzaktan imzalayan bir kişiyle imzalamak istiyorum: İki adımlı akışın adım adım açıklaması.
- Dijital imza: İmzacı iletiyi görebildiğinde tek adımda imzalama ve doğrulama.
- Dile göre desteklenen temel anahtar türleri
- Tink tel biçimi: Tink'i başka bir dile aktarmak için ön karma değerinin bayt düzeyindeki düzeni.