Özel anahtarın mesajın gönderilemediği bir yerde bulunduğu durumlarda ML_DSA_44 anahtarıyla Prehash ve SignPrehash ilkel işlevlerini kullanmanızı öneririz.
İmzalama anahtarını elinde bulunduran taraf bazen iletinin kendisini alamaz veya almamalıdır: Anahtar bir HSM'de ya da KMS'de bulunur veya ileti, imzalayanın istek boyutu sınırından daha büyüktür.
Prehash ve SignPrehash temel işlevleri, imzalama işlemini iki adıma bölerek bu sorunu çözer. Yalnızca ortak anahtarı kullanarak mesajın bulunduğu yerde kısa bir ön karma değeri hesaplar ve bunu imzalayana gönderirsiniz. İmzalayan, iletiyi hiç görmeden özel anahtarı kullanarak imzaya dönüştürür. Tink'in desteklediği algoritma olan Harici Mu modunda ML-DSA ile, mesajın boyutu ne olursa olsun ön karma değeri 69 bayttır.
Geri aldığınız imza, orijinal mesajın normal bir imzasıdır: Doğrulayıcılar, normal dijital imza temelini kullanır ve iki adımın kullanıldığını bilmeleri gerekmez.
Başlamadan önce
Anahtarlarının kimlik şartı olan bir ML-DSA anahtar grubu oluşturun. Bu şart, TINK varyantı veya sonuçtaki imzaya çıkış öneki eklemek istemiyorsanız NO_PREFIX_WITH_PREHASH_ID olabilir. İmzalayana özel anahtar kümesini ve ön karma oluşturma tarafına karşılık gelen ortak anahtar kümesini verin. İmzalayan, ön karma oluşturma tarafının oluşturabileceği her anahtar kimliği için etkin bir anahtara sahip olmalıdır. Anahtar kümeleri bölümüne bakın.
1. adım: Ön karma değerini hesaplayın
Bu işlevi, mesajın bulunduğu her yerde çalıştırın. Yalnızca ortak anahtar kümesi gerekir.
C++
#include "tink/keyset_handle.h" #include "tink/signature/config_2026.h" #include "tink/signature/prehash.h" absl::StatusOr<std::unique_ptr<crypto::tink::Prehash>> prehasher = public_handle.GetPrimitive<crypto::tink::Prehash>( crypto::tink::ConfigSignature2026()); if (!prehasher.ok()) return prehasher.status(); absl::StatusOr<std::string> prehash = (*prehasher)->Compute(message); if (!prehash.ok()) return prehash.status();
Go
import "github.com/tink-crypto/tink-go/v2/signprehash" prehasher, err := signprehash.NewPrehash(publicHandle) if err != nil { return err } prehash, err := prehasher.ComputePrehash(message) if err != nil { return err }
Python
from tink import signature # Due to the internal structure of Tink Python, Prehash and SignPrehash # are an exception where calling signature.register() is not necessary. # Do not expect the same for other primitives (such as PublicKeyVerify in # Step 4). prehasher = public_handle.primitive(signature.Prehash) prehash = prehasher.compute(message)
2. adım: Ön karma oluşturma değerini imzalayana gönderin
Önceden karma oluşturulmuş değeri, özel anahtarı tutan yere gönderin. Gizli olmasa da iletim sırasında bütünlüğünü korumanız gerekir: Uçuş sırasında değiştirebilen bir saldırgan, neyin imzalanacağını kontrol eder.
3. adım: Ön karma değerini imzalayın
Bu komutu, özel anahtarın bulunduğu her yerde çalıştırın.
C++
#include "tink/keyset_handle.h" #include "tink/signature/config_2026.h" #include "tink/signature/sign_prehash.h" absl::StatusOr<std::unique_ptr<crypto::tink::SignPrehash>> signer = private_handle.GetPrimitive<crypto::tink::SignPrehash>( crypto::tink::ConfigSignature2026()); if (!signer.ok()) return signer.status(); absl::StatusOr<std::string> signature = (*signer)->Sign(prehash); if (!signature.ok()) return signature.status();
Go
import "github.com/tink-crypto/tink-go/v2/signprehash" signer, err := signprehash.NewPrehashSigner(privateHandle) if err != nil { return err } sig, err := signer.SignPrehash(prehash) if err != nil { return err }
Python
from tink import signature # Due to the internal structure of Tink Python, Prehash and SignPrehash # are an exception where calling signature.register() is not necessary. # Do not expect the same for other primitives (such as PublicKeyVerify in # Step 4). signer = private_handle.primitive(signature.SignPrehash) sig = signer.sign(prehash)
4. adım: İmzayı doğrulayın
Doğrulama, ön karma değeri üzerinden değil, orijinal ileti üzerinden yapılan normal dijital imza akışıdır.
C++
absl::StatusOr<std::unique_ptr<crypto::tink::PublicKeyVerify>> verifier = public_handle.GetPrimitive<crypto::tink::PublicKeyVerify>( crypto::tink::ConfigSignature2026()); if (!verifier.ok()) return verifier.status(); absl::Status verified = (*verifier)->Verify(signature, message);
Go
import "github.com/tink-crypto/tink-go/v2/signature" verifier, err := signature.NewVerifier(publicHandle) if err != nil { return err } if err := verifier.Verify(sig, message); err != nil { return err }
Python
from tink import signature signature.register() verifier = public_handle.primitive(signature.PublicKeyVerify) verifier.verify(sig, message)
Prehash ve SignPrehash
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. Bu imzayı 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.
Ön karma değerini opak baytlar olarak değerlendirin. Sabit bir boyuta sahiptir 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'in kablo biçimi bölümüne bakın.
Bu temel öğe çiftini şu durumlarda kullanın:
- İmzalama anahtarı başka bir yerde bulunuyorsa (ör. HSM, KMS veya RPC sınırı içinde) ve tam mesajı bu sınırın ötesine göndermek istemiyorsanız.
- İleti büyük ve uzaktan imzalayan, istek boyutu sınırı uyguluyor.
Bu durumlardan 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, anahtarları farklı şekilde seçer. Bu, imzalama ve doğrulamanın dijital imza temelinde yaptığıyla aynıdır:
Prehash.Compute, her 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 setinde bu kimliğe sahip etkin bir anahtar yoksa arama başarısız olur.
SignPrehash anahtar grubundaki 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 Dijital İmza temel öğ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 ön ek ekler.
SignPrehashdeğeri yalnızca bu anahtarla imzalar. Değerin bu anahtara kriptografik olarak bağlı olup olmadığı algoritmaya bağlıdır. Harici Mu ML-DSA için bu durum geçerlidir. Tink tel biçimine bakın. - Mesajlar herhangi bir uzunlukta olabilir.
Dikkat etmeniz gerekenler
- İmzalayan kişi, imzaladığı şeyi inceleyemez.
SignPrehashkullanıcısına telefon edebilen herkes rastgele bir mesajı imzalayabilir ve imzalayan, mesaj içeriklerine politika uygulayamaz.SignPrehashhizmetine erişimi,PublicKeySignhizmetine erişimi koruduğunuz şekilde koruyun. - Karma oluşturma işleminden önceki değeri geçiş sırasında koruyun. Gizli olmasa da saldırgan, uçuş sırasında değiştirebildiği için neyin imzalanacağını kontrol eder.
Anahtar türü seçin
External Mu modunda ML-DSA, RFC 9881'de açıklandığı gibi, Tink'in Prehash ve SignPrehash için desteklediği tek algoritmadır. Bu temel öğelerle standart bir ML-DSA anahtarı kullanmanız gerekir.
Çoğu kullanım alanı için ML_DSA_44'ü öneririz.
Her karma oluşturma öncesi değer, hesaplandığı anahtarın kimliğini içeren bir önekle başladığı için anahtarın kimlik şartı olmalıdır. Aşağıdaki varyantlar kabul edilir:
TINK: Ortaya çıkan imza, Tink'in normal 5 baytlık çıkış ön ekiyle başlar.NO_PREFIX_WITH_PREHASH_ID-- Sonuçta elde edilen imza, çıkış ön eki 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.