SORU
26 EKİM 2012, Cuma


Microsoft Crypto API RSAES-OAEP Anahtar Taşıma Algoritma Kullanımını Devre dışı bırakın

CryptEncryptMessage PKCS#7 zarflı bir mesaj oluşturmak için kullanıyorum. Şifreleme algoritması olarak szOID_NIST_AES256_CBC kullanıyorum.

Oluşturulan mesaj geçerli görünüyor ama vahşi desteği (Thunderbird, diğerleri arasında Modül desteği yok OpenSSL SMIME) sınırlı olan Anahtar Taşıma Algoritma için RSAES-OAEP.

PAUSE için RSAencryption anahtar için eski ulaştırma dönmek istiyorum.

Herhangi bir şekilde bunu yapmak için, elimden dönmek için düşük seviye mesajlaşma fonksiyonları varsa bir şekilde yerine kullanın CryptEncryptMessage ama bulamıyorum bir şekilde bunu bile kullanarak düşük seviye fonksiyonlar.

Kod:

CRYPT_ENCRYPT_MESSAGE_PARA EncryptMessageParams;
EncryptMessageParams.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);

EncryptMessageParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING;

EncryptMessageParams.ContentEncryptionAlgorithm.pszObjId = szOID_NIST_AES256_CBC;
EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.cbData = 0;
EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.pbData = 0;

EncryptMessageParams.hCryptProv = NULL;
EncryptMessageParams.pvEncryptionAuxInfo = NULL;
EncryptMessageParams.dwFlags = 0;
EncryptMessageParams.dwInnerContentType = 0;

BYTE pbEncryptedBlob[640000];
DWORD pcbEncryptedBlob = 640000;

BOOL retval =  CryptEncryptMessage(&EncryptMessageParams, cRecipientCert, pRecipCertContextArray, pbMsgText, dwMsgTextSize, pbEncryptedBlob, &pcbEncryptedBlob);

CEVAP
27 EKİM 2014, PAZARTESİ


Anahtar Taşıma Algoritma biraz zor handle değil hizmet amacı (görüyorum ettiğiniz istersin JET için destek RSAencryption; güven bana, ben de isterdim). Alaready senin sorunun çoğunu tespit ettik gibi görünüyorOluşturulan iletisi görüntülenir geçerlidir, ama senin yöntem gerekli şey/uzun vadede işe yaramaz ki CryptEncryptMessage, kullanımı kolay hale getirir.

Adım 1 - Aşağıdaki Kodu İnceleyin

CRYPT_ENCRYPT_MESSAGE_PARA EncryptMessageParams;
EncryptMessageParams.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);

EncryptMessageParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING;

EncryptMessageParams.ContentEncryptionAlgorithm.pszObjId = szOID_NIST_AES256_CBC;
EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.cbData = 0;
EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.pbData = 0;

EncryptMessageParams.hCryptProv = NULL;
EncryptMessageParams.pvEncryptionAuxInfo = NULL;
EncryptMessageParams.dwFlags = 0;
EncryptMessageParams.dwInnerContentType = 0;

BYTE pbEncryptedBlob[640000];
DWORD pcbEncryptedBlob = 640000;

BOOL retval =  CryptEncryptMessage(&EncryptMessageParams, cRecipientCert, pRecipCertContextArray, pbMsgText, dwMsgTextSize, pbEncryptedBlob, &pcbEncryptedBlob);

Oldukça basit, değil mi? Verimli olmasına rağmen, gerçekten sorunu halletmek için değil. Şuna bir bakarsanız:

EncryptMessageParams.dwFlags = 0;
EncryptMessageParams.dwInnerContentType = 0;

ön tanımlı olduğunu göreceksiniz, ama retval tanımı geçerlidir. Ancak, kesinlikle bu mikro-optimizasyon olarak, ve eğer yeniden yazmak için gidiyoruz eğer gerçekten yararlı görebiliyordum kodu. Ancak, temel adımlar, darbe kod aynı parametreleri kullanarak tutmak (toplam yeniden olmadan bu entegre çıkardım:

Adım 2 - Parametrelerini Düzenleme

@Yorumlarda bahsedilen owlstead olarak, Kripto API kullanıcı dostu değildir. Ancak, kısıtlı imkanlarla büyük bir iş başardınız. Eklemek istemiyorsan ne yapacaksın anahtarları daraltmaya yardımcı olacak Cryptographic Enumeration Provider. Bu verimli bir şekilde kullanmak için Sağlayıcı sürüm 1.0 veya Microsoft Gelişmiş Şifreleme Sağlayıcısı sürüm 1.0 Şifreleme ya da Microsoft Temel olduğundan emin olun. Aksi halde, böyle bir fonksiyon eklemek gerekir:

DWORD cbName;
DWORD dwType;
DWORD dwIndex;
CHAR *pszName = NULL;
(regular crypt calls here)

Bu temelde, teknik olarak düşük seviyede daha fazla bir bildiri ile bunu önlemek, ancak NTE_BAD_FLAGS hata önlemek için kullanılır. Eğer istersen, ayrıca yepyeni bir karma bu yukarıdaki uygulama/saat hız gerekli faktör ölçek kazanırsa mi gerekli olmasına rağmen () oluşturabilirsiniz:

DWORD dwBufferLen = strlen((char *)pbBuffer) 1*(0 5);
HCRYPTHASH hHash;
HCRYPTKEY hKey;
HCRYPTKEY hPubKey;
BYTE *pbKeyBlob;
BYTE *pbSignature;
DWORD dwSigLen;
DWORD dwBlobLen;
(use hash as normal w/ crypt calls and the pbKeyBlobs/Signatures)

Emin geçmeden önce bu parçacık vaildate. Bu kadar kolay gibi yapabilirsiniz:

if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
     printf("CSP context acquired.\n");
}

Eğer belgeleyen ya da serbest iseniz, void MyHandleError(char *s) bir düzenleme kişi bir hata yakalamak için eklemek isteyebilirsiniz ama başarısız hızlı bir şekilde yakalayabilirsiniz.

Bu arada, ilk kez çalıştırdığınızda varsayılan yok çünkü yeni bir takım oluşturmak Zorundasınız. if aklıma bir espri güzel aşağıdadır:

CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)

Sunucu kaynaklarını senkronize unutmayındeğililk adımda önerdim yeniden iş yapmaya kadar etkili. Bu aşağıda anlatan olacaktır:

3 - Filmin ve Kampanyayı adım

Bir programcı olarak, kodlama yeniden bir zaman kaybı gibi görünebilir, ama kesinlikle uzun vadede yardımcı olabilir. Hala/senkronizasyon kodlama özel parametreler kod gerekecek unutmayın; besleme el tüm kod bebek gibi yapmayacağım. İyi göstermek için yeterli olması gereken temel özetliyor.

Kesinlikle geçerli kullanıcının anahtar kabı için idare etmeye çalıştığını sanıyorumbelirli bir CSP içinde; aksi halde, bunu gerçekten görmek istemiyorum. Değilse, bazı temel düzenlemeler ihtiyaçlarınıza göre yapabilirsiniz.

Unutmayın, doğrudan CryptAcquireContext işlevi tarafından elde ele bültenleri CryptReleaseContext kullanarak CryptEncryptMessage atlamak için gidiyoruz. CAC Microsoft'un standart aşağıdaki gibidir:

BOOL WINAPI CryptAcquireContext(
  _Out_  HCRYPTPROV *phProv,
  _In_   LPCTSTR pszContainer,
  _In_   LPCTSTR pszProvider,
  _In_   DWORD dwProvType,
  _In_   DWORD dwFlags
);

Microsoft eğer bir kullanıcı arayüzü kullanıyorsanız: azarlamak olduğunu unutmayın

Eğer CSP çalışmasına UI görüntülemek gerekiyorsa, çağrı başarısız olur ve NTE_SİLENT_CONTEXT hata kodu son hata olarak ayarlanır. Eğer aramalar CRYPT_SİLENT bayrağı ile elde edilmiş bir bağlam ile CRYPT_USER_PROTECTED bayrağı ile CryptGenKey için yapılır ayrıca, eğer, bu çağrılar başarısız olur ve CSP NTE_SİLENT_CONTEXT ayarlar.

Bu Özellikle sunucu Kodu ve ERROR_BUSY kesinlikle birden fazla bağlantı, özellikle yüksek bir gecikme ile bu olduğunda yeni kullanıcılar için görüntülenir. Yukarıda 300ms aradı NTE_BAD_KEYSET_PARAM bir ya da benzer, hatta uygun bir hata aldı olmadan zaman aşımı nedeniyle neden olur. (İletim sorunları, benimle gelen var mı?)

Sürece seni endişelendirdiğini birden fazla DLL (ki bu yok destek nedeniyle NTE_PROVIDER_DLL_FAIL hataları), temel kurmak için yakala crypt Hizmetleri istemci tarafı olacağını olarak aşağıda (kopyalanan doğrudan Microsoft'un örnek):

if (GetLastError() == NTE_BAD_KEYSET)
 {
   if(CryptAcquireContext(
      &hCryptProv, 
      UserName, 
      NULL, 
      PROV_RSA_FULL, 
      CRYPT_NEWKEYSET)) 
    {
      printf("A new key container has been created.\n");
    }
    else
    {
      printf("Could not create a new key container.\n");
      exit(1);
    }
  }
  else
  {
      printf("A cryptographic service handle could not be "
          "acquired.\n");
      exit(1);
   }

Bu gibi görünebilir ancak basit, kesinlikle sıkışmış bu anahtar değişim algoritması (ya da her ne olursa olsun bu işleme var) geçmesini istemiyorum. Simetrik oturum anahtarları (Diffie-Hellman/KEA) kullanmıyorsanız, exchange anahtarı güvenle saklanabilir, böylece oturum anahtarları şifrelemek için kullanılan ve diğer kullanıcılar ile değiş tokuş edilebilir.

Biri John Howard adlı Hyper-V Uzaktan güzel bir Yönetim yazmıştır burada açıklanan teknikler geniş bir derleme olan Yapılandırma Programı (HVRemote). Temel kript ve keypairs kullanarak ek olarak, ANONYMOUS LOGON DCOM uzaktan erişim (özel olarakcscript hvremote.wsf,) izin vermek için kullanılabilir. Bir çok işlev ve kendi blogunda yaptığı son kript (sorgu dar gerekecek): teknikleri görebilirsiniz

http://blogs.technet.com/b/jhoward/

Eğer temelleri ile daha fazla yardıma ihtiyacınız varsa, bir yorum bırakın ya da özel bir sohbet isteği.

Sonuç

Temel sunucu tarafı sağlama yöntemleri ve müşteri kapmak", hatta iletir sırasında şifreleme çalıştı. neden sorgulama olacaksın" kript nasıl olduğunu fark edince çok basit olmasına rağmen Ancak, crypting istemci tarafı olmadan, şifreler kesinlikle zaten karma ne iletmek için sadece güvenli yol olacaktır.

Paketlerin şifresi savunuyor ve tuzları karma kapalı olsa da, giden ve doğru zamanlama işlenmiş saklı olabileceğini düşününvesipariş re-hash için gerekli istemci tarafı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jon Reed

    Jon Reed

    14 AĞUSTOS 2006
  • Tom Megalis

    Tom Megalis

    18 NİSAN 2006
  • whiteboy7thst

    whiteboy7ths

    1 Temmuz 2009