robotk <robotk_at_163.com> writes:
> suggest a new feature: adding smart card support to windows svn client in
> version 1.5
Search for "smartcard" in http://svn.collab.net/repos/svn/trunk/CHANGES,
you will see it's in upcoming 1.5.0.
-Karl
> Hi:
> Maybe someone have posted this suggestion before, and the Linux build now can
> support smart card thanks to Joe Orton's greate work(http://svn.haxx.se/users/
> archive-2008-04/0377.shtml).
> I think it is not difficult to implement this feature on windows. Last month,
> we made an effort to implement smart card authentication by using Microsoft's
> CSP and openSSL library. We found that it is simple to manipulate the smart
> card by CSP API. Microsoft's CSP is a software interface standard. Almost all
> the smart card manufacturers support this standard and provide the software
> realization(dll). The CSP standard allows us to use the public-private key
> pair to encrypt,decrypt data and sign message digest while know nothing about
> the hardware details. All the CSPs are registered in HKEY_LOCAL_MACHINE\
> SOFTWARE\Microsoft\Cryptography\Defaults\Provider. This page(http://
> msdn.microsoft.com/en-us/library/aa380245%28VS.85%29.aspx) describes the CSP in
> detail.
> Most smart card manufacturers also provide a standards-based PKCS#11 library.
> PKCS#11(http://www.rsa.com/rsalabs/node.asp?id=2133) is a cryptographic token
> interface standard developed by RSA laboratories. It is the counterpart of
> Microsoft's CSP. PuTTY, openVPN and some other software on windows platform use
> PKCS#11 instead of CSP. The specifications of the PKCS#11 standard are
> described in ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf.
>
> The following are several typical examples of using CSP API. (without error
> handling)
> All the CSP APIs are declared in header file wincrypt.h.
> 1. Enumerate all the certificates stored in USB KEY:
> #include <wincrypt.h>
> #pragma comment(lib, "crypt32.lib")
> HCRYPTPROV hCryptProv = NULL;
> CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
> CRYPT_VERIFYCONTEXT);
> HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
> hCryptProv, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
> // just access to the publicly available information, the CSP would not ask
> for a PIN
> PCCERT_CONTEXT pCertContext = NULL;
> while (1)
> {
> pCertContext = CertEnumCertificatesInStore (hCertStore, pCertContext);
> if (!pCertContext) break;
> //suppose the maximum length of all the fileds doesn't exceed 512
> const int iMaxFldLen = 512;
> char szSubjectName[iMaxFldLen]={0}, szIssuerName[iMaxFldLen]={0};
> // get common name,
> CertGetNameString (pCertContext, CERT_NAME_ATTR_TYPE, NULL,
> szOID_COMMON_NAME, szSubjectName, iMaxFldLen);
> // get issuer name
> CertGetNameString (pCertContext, CERT_NAME_ATTR_TYPE,
> CERT_NAME_ISSUER_FLAG,
> szOID_COMMON_NAME, szIssuerName, iMaxFldLen);
> printf ("%s %s\n", szSubjectName, szIssuerName);
> // get the CSP name and key container name
> char szContName[iMaxFldLen]={0}, szProvName[iMaxFldLen]={0}, pvData
> [iMaxFldLen]={0};
> DWORD cbData = iMaxFldLen;
> CertGetCertificateContextProperty (pCertContext,
> CERT_KEY_PROV_INFO_PROP_ID, pvData, &cbData);
> CRYPT_KEY_PROV_INFO* pProvInfo = (CRYPT_KEY_PROV_INFO *)pvData;
> sprintf (szContName, "%S", pProvInfo->pwszContainerName);
> sprintf (szProvName, "%S", pProvInfo->pwszProvName);
>
> printf ("%s %s\n", szContName, szProvName);
> // get other fields of the X509 certificate
> // ...
> }
> CryptReleaseContext (hCryptProv, 0); // release the handle
>
> 2. Using private key stored in the USB KEY to sign the digest of message
> #include <wincrypt.h>
> #pragma comment(lib, "crypt32.lib")
> // the container name and CSP name can be retrieved in example 1
> // char szContName[] = {"61aecdd2-65b4-4919-a56c-0b2f5f7833d1"};
> // char szProvName[] = {"SafeSign CSP Version 1.0"};
> char szMsg[] = {"something"};
> DWORD dwMsgLen = strlen(szMsg);
> HCRYPTPROV hCryptProv = NULL;
> CryptAcquireContext (&hCryptProv, szContName, szProvName, PROV_RSA_FULL,
> 0);
> HCRYPTHASH hHash = NULL;
> CryptCreateHash (hCryptProv, CALG_MD5, 0, 0, &hHash);
> CryptHashData (hHash, (BYTE*)szMsg, dwMsgLen, 0);
> DWORD dwSignLen = 0;
> CryptSignHash (hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSignLen);
> char* szSignBuf = (char*) malloc(dwSignLen*sizeof(char));
> if (!CryptSignHash (hHash, AT_SIGNATURE, NULL, 0, (BYTE*)szSignBuf, &
> dwSignLen))
> {
> printf ("CryptSignHash failed\n");
> }
> else
> {
> printf ("CryptSignHash done\n");
> }
>
> free (szSignBuf);
> CryptReleaseContext (hCryptProv, 0); // release the handle
>
> 3. Using private key to decrypt the ciphertext encrypted by the public key
> #include <wincrypt.h>
> #pragma comment(lib, "crypt32.lib")
> // the container name and CSP name can be retrieved in example 1
> // char szContName[] = {"61aecdd2-65b4-4919-a56c-0b2f5f7833d1"};
> // char szProvName[] = {"SafeSign CSP Version 1.0"};
> char pEncryptedData[] = {"top secret encrypted by public key"};
> DWORD dwEncryptDataLen = strlen(pEncryptedData);
> HCRYPTPROV hCryptProv = NULL;
> CryptAcquireContext (&hCryptProv, szContName, szProvName, PROV_RSA_FULL,
> 0);
> HCRYPTKEY hUserKey = NULL;
> BOOL bRet= CryptGetUserKey (hCryptProv, AT_KEYEXCHANGE, &hUserKey);
> // pEncryptedData point to the ciphertext encrypted by the public key and
> // dwEncryptDataLen is the length of the ciphertext
> if (!CryptDecrypt(hUserKey, 0, true, 0, (BYTE*)pEncryptedData, &
> dwEncryptDataLen))
> {
> // CryptDecrypt() will failed if the pEncryptedData was NOT
> // encrypted by the corresponding public key
> printf ("CryptDecrypt failed\n");
> }
> else
> {
> printf ("CryptDecrypt done\n");
> }
> // now pEncryptedData point to plaintext and
> // dwEncryptDataLen is the length of the plaintext
> CryptReleaseContext (hCryptProv, 0);
>
>
>
> Thanks
>
> Setven Zhang
>
>
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
> 上房老大买二手房,看实景照片,挑专业经纪人
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-06-12 09:54:34 CEST