2010-09-02 64 views
7

Tôi đang cố xác thực chứng chỉ X.509 bằng C# và .NetCF. Tôi có chứng chỉ CA và nếu tôi hiểu chính xác, tôi cần sử dụng khóa công khai từ chứng chỉ CA này để giải mã chữ ký của chứng chỉ không đáng tin cậy. Điều này sẽ cho tôi giá trị băm được tính toán của chứng chỉ không đáng tin cậy. Sau đó tôi nên tính toán giá trị băm của chứng chỉ và đảm bảo hai giá trị khớp nhau.Cách xác thực Chứng chỉ X.509 trong C# bằng Compact Framework

Tôi đã chơi với điều này trong một vài ngày và tôi không nhận được rất xa. Tôi đã sử dụng các lớp X509Certificate và RSACryptoServiceProvider. Đầu tiên, tôi đã cố gắng lấy khóa công khai và chữ ký ra khỏi lớp X509Certificate. Tôi đã có thể lấy chìa khóa công khai nhưng không có chữ ký. Tiếp theo, tôi đã thử phân tích cú pháp dữ liệu nhị phân tạo chứng chỉ, cho phép tôi lấy chữ ký (và bất kỳ dữ liệu nào khác mà tôi muốn), nhưng tôi không thể giải mã chữ ký bằng RSACryptoServiceProvider. Tôi đã thử những thứ như thế này nhưng vẫn giữ ngoại lệ nói "Bad Key" khi tôi cố gắng giải mã:

RSAParameters rsaParams = new RSAParameters(); 
rsaParams.Exponent = exp; 
rsaParams.Modulus = mod; 
RSACryptoServiceProvider rsaServ = new RSACryptoServiceProvider(); 
rsaServ.ImportParameters(rsaParams); 
byte[] decryptedSig = rsaServ.Decrypt(encryptedSig, false); 

Mọi lời khuyên sẽ được đánh giá cao.

Chỉnh sửa: Tôi đã thử một cái gì đó có vẻ tốt hơn nhưng đang trả lại kết quả lạ. Tôi đang làm việc với lớp X509Certificate2 ở đây vì nó dễ dàng hơn một chút để thử nghiệm, nhưng tôi sẽ cần phải chuyển sang X509Certificate cho .NetCF sau. Tôi nghĩ rằng RSACryptoServiceProvider.VerifyData có thể là những gì tôi cần. Tôi đã thử đoạn mã sau.

X509Certificate2 cert = new X509Certificate2(certBytes); 
X509Certificate2 certCA1 = new X509Certificate2(@"C:\certs\certCA1.cer"); 

byte[] encryptedSig = new byte[256]; 
Array.Copy(certBytes, certBytes.Length - 256, encryptedSig, 0, 256); 

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certA1.PublicKey.Key; 
bool good = rsa.VerifyData(cert.RawData, "1.3.14.3.2.26", encryptedSig); 

Như tôi đã nói, tôi có thể tự giải mã và giải thích các dữ liệu nhị phân của giấy chứng nhận, vì vậy tôi khá chắc chắn rằng cert.RawData là dữ liệu ký của chứng chỉ và 256 byte cuối cùng là chữ ký được mã hóa . Chuỗi là OID của thuật toán băm, mà tôi nhận được từ chứng chỉ, nhưng tôi không chắc chắn 100% là nó đúng. VerifyData trả về false, nhưng tôi vẫn chưa chắc tại sao.

Suy nghĩ?

Trả lời

3

Đây là của tôi mã.

RSACryptoServiceProvider rsa = signingCertificate_GetPublicKey(); 
return rsa.VerifyData(SignedValue(), CryptoConfig.MapNameToOID("SHA1"), Signature()); 

RSACryptoServiceProvider signingCertificate_GetPublicKey() 
{ 
    RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider(); 

    RSAParameters publicKeyParams = new RSAParameters(); 
    publicKeyParams.Modulus = GetPublicKeyModulus(); 
    publicKeyParams.Exponent = GetPublicKeyExponent(); 

    publicKey.ImportParameters(publicKeyParams); 

    return publicKey; 
} 

byte[] GetPublicKeyExponent() 
{ 
    // The value of the second TLV in your Public Key 
} 

byte[] GetPublicKeyModulus() 
{ 
    // The value of the first TLV in your Public Key 
} 

byte[] SignedValue() 
{ 
    // The first TLV in your Ceritificate 
} 

byte[] Signature() 
{ 
    // The value of the third TLV in your Certificate 
} 

Tôi hy vọng rằng sẽ giúp bất kỳ ai đang giải quyết vấn đề này.

1

WinCE có hỗ trợ điều gì đó tương thích với Win32 MSCrypto.dll không? Nếu có, hãy xem lớp .NET X509Certificate2 và cũng là CLR Security library on Codeplex. Nó chứa rất nhiều thói quen hữu ích cho .NET nằm trên thư viện mã hóa hệ điều hành lõi. Bạn có thể tải về mã nguồn và xem nó như thế nào biên dịch cho .NetCF

Để tải và xác nhận một giấy chứng nhận X509, làm một cái gì đó như thế này (chưa được kiểm tra):

var cert = new X509Certificate2("mycert.cer"); 
if (!cert.Verify()) 
{ 
    <fail> 
} 

Có gần một chục nhà xây dựng cho X509Certificate2 để xây dựng từ nhiều nguồn khác nhau - tệp trên đĩa, mảng byte trong bộ nhớ, tải từ cửa hàng cert cục bộ, v.v.

Gốc CA được sử dụng để ký chứng chỉ sẽ cần được cài đặt trong cửa hàng cert cục bộ. Nếu chứng chỉ không bao gồm các CA trung gian trong chuỗi tin cậy, các trung gian đó cũng sẽ cần phải nằm trên máy cục bộ, tất cả các con đường đến một CA gốc nằm trong kho lưu trữ tin cậy trong máy cục bộ.

Thật không may, tôi không thể nói từ tài liệu MSDN cho dù X509Certificate2 có sẵn trên .NetCF.

+0

Những hạn chế của WinCE có thể khó khăn và tôi hoàn toàn mới với X.509, vì vậy tôi đã cố gắng làm việc này trong môi trường Win32 bình thường trước và thậm chí tôi không thể làm điều đó. Tôi đã xem xét thư viện CLR Security mà bạn đã chỉ ra, nhưng tôi không thấy bất cứ điều gì ở đó để xác nhận chứng chỉ X509. Bạn có thể cho tôi thêm một chút để tiếp tục không? – Ben

+0

Tôi đã cập nhật câu trả lời bằng mã mẫu. – dthorpe

+0

X509Certificate2 không khả dụng trên. NetCF, nhưng điều này rất hữu ích. Cảm ơn. – Ben

0

Nó làm việc cho tôi trong win32, nhưng trong Compact Framework Tôi đang phải đối mặt với cùng một vấn đề, không có X509Certificate2 vì vậy tôi thực sự bị chặn, với win32 chúng ta có thể làm:

X509Certificate2 l__PublicKeyCertificate = new X509Certificate2("cert.cer"); 

RSACryptoServiceProvider l__rsaCspPublic = (RSACryptoServiceProvider)l__PublicKeyCertificate .PublicKey.Key; 

//... 

l__isVerified = l__rsaCspPublic.VerifyData(l__fileData, CryptoConfig.MapNameToOID("SHA1"), l__fileSignature); 
+0

Tôi đã tìm ra điều này một lúc trước và quên đăng câu trả lời. Tôi sẽ xem xét mã nguồn của tôi và nhận câu trả lời được đăng vào thứ Hai. – Ben

Các vấn đề liên quan