Xây dựng các chức năng chính của chương trình

Một phần của tài liệu Sử dụng chữ ký điện tử để xác thực trong quản lý công văn đi đến (Trang 54)

2. Thiết kế chương trình

2.2.Xây dựng các chức năng chính của chương trình

Chương trình có 2 module: Module quản trị, module quản lý văn bản nhân viên quản trị sẽ tạo các luồng văn bản để người dùng soạn thảo và gửi chúng cho thủ trưởng kiểm tra và phê duyệt, ký và phát hành chúng tới các đơn vị. Tại đây người dùng có thể kiểm tra tính xác thực của văn bản bằng module kiểm tra chữ ký số RSA.

49

2.2.1. Quản trị hệ thống

Hình III.2.1 – Biểu đồ Use Case của người quản trị

Các công việc của người quản trị:

- Quản lý người dùng: Tạo, quản lý các tài khoản người dùng, quy định vị trí, chức vụ của người dùng, phân quyền chức năng và quyền hạn trong hệ thống cho các tài khoản.

- Quản lý danh mục: Tạo các danh mục chức năng cho hệ thống và cho các văn bản sử dụng: Phòng ban, chức vụ, độ mật văn bản, cơ quan ban hành, thẩm quyền ban hành, chức vụ của người ký và soạn thảo văn bản…

- Quản lý luồng văn bản: Tạo các luồng xử lý văn bản cho phép quy định việc văn bản được tạo ra sẽ được gửi cho ai, những người được tham gia vào quy trình xử lý loại văn bản này, người ký, phê duyệt văn bản, các cơ quan nhận văn bản đến khi nó được phát hành…

50

- Quản lý khóa: Tạo và phân phối các cặp khóa riêng và khóa công khai cho người dùng phục vụ cho việc ký duyệt, kiểm tra và mã hóa văn bản.

2.2.2. Quản lý văn bản đi và đến

Hình III.2.2.2 (1) – Biểu đồ Use Case của người dùng

- Văn bản đi: là tất cả các loại văn bản, bao gồm văn bản quy phạm pháp luật, văn bản hành chính và văn bản chuyên ngành (kể cả bản sao văn bản, văn bản nội bộ và văn bản mật) do cơ quan, tổ chức phát hành.

- Văn bản đến: là tất cả các loại văn bản, bao gồm văn bản quy phạm pháp luật, văn bản hành chính và văn bản chuyên ngành (kể cả bản Fax, văn bản được chuyển qua mạng, văn bản mật) và đơn, thư gửi đến cơ quan, tổ chức.

51

Hình III.2.2.2 (2) – Các thành phần cơ bản của một văn bản số

* Các tình trạng chính của văn bản:

- Văn bản đang dự thảo. - Văn bản trả lại.

- Văn bản xin ý kiến. - Văn bản chờ xử lý. - Văn bản đã xử lý. - Văn bản đã phát hành. - Tìm kiếm. - Hồ sơ lưu trữ. * Các tính năng cơ bản:

- Đính kèm tài liệu theo văn bản.

- Hỗ trợ soạn thảo và in văn bản theo các mẫu chuẩn.

- Cung cấp thư viện mẫu chuẩn các loại văn bản theo quy định. - Tự động gửi văn bản theo luồng đã được định nghĩa.

52

- Xem, chỉnh sửa văn bản và theo dõi ý kiến xử lý. - Tích hợp chữ ký số khi ký duyệt văn bản.

Tin học hóa quy trình gửi, nhận, duyệt chuyển và quản lý một cách hệ thống các văn bản đến, đi theo chức năng, nhiệm vụ đối với tất cả các cấp. Các văn bản được quản lý ở dạng toàn văn với các định dạng khác nhau. Luồng xử lý văn bản diễn ra theo một tiến trình được quy định trước và có thể thay đổi linh hoạt theo ý đinh của người quản trị mà vẫn đảm bảo hệ thống hoạt động bình thường. Qua đó quá trình xử lý văn bản được lưu lại dấu vết một cách chi tiết phục vụ công tác quản lý, theo dõi, báo cáo.

Các thành viên tham gia xử lý văn bản có vai trò khác nhau tùy mục đích khi phát hành văn bản, công văn được quy định trong luồng nhưng nhìn chung đều tuân theo các công việc chính sau đây:

53

Hình III.2.2.2 (3) – Biểu đồ trình tự quản lý văn bản

- Văn thư nhận chỉ thị soạn thảo các văn bản theo nội dung và thể thức (mẫu có sẵn). Sau khi cập nhật xong, văn thư gửi văn bản đó cho thủ trưởng xử lý.

- Thủ trưởng phòng/ban xem xét, duyệt nội dung văn bản, kiểm tra thể thức, nếu phát hiện sai sót thì gửi trả lại cho văn thư sửa chữa và xử ls, nếu đã hợp lệ thì ký duyệt (bằng chữ ký số nếu cần thiết) rồi gửi cho trợ lý của phòng ban.

- Sau khi trợ lý tiếp nhận văn bản đã được ký duyệt, văn thư có thể kiểm tra lại tính toàn vẹn của văn bản bằng chữ ký số, nếu hợp lý thì tiến hành phát hành văn bản tới các phòng ban cần thiết, trở thành văn bản đến các đơn vị. (adsbygoogle = window.adsbygoogle || []).push({});

54

- Văn thư ở các đơn vị tiếp nhận văn bản đến và lặp lại quy trình trên.

Ví dụ về 1 luồng với quy trình xử lý văn bản đi cơ bản:

Hình III.2.2.2 (4) – Ví dụ luồng văn bản

2.3. Ký số bằng phương pháp RSA khi phê duyệt văn bản a. Phát sinh khóa:

Từ cặp số nguyên tố bất kỳ ban đầu, chương trình sẽ thực hiện tính toán để đưa ra cặp khóa công khai (e, n) và khóa bí mật (d, n). Sau đó khóa công khai được tiết lộ ra công cộng, khóa bí mật được giữ lại.

b. Ký chữ ký điện tử:

Khi một người muốn gửi cho ai đó một văn bản quan trọng, đòi hỏi văn bản phải được ký xác nhận chính danh người gửi văn bản, người gửi văn bản sẽ làm thực hiện quy trình ký chữ ký điện tử.

Qui trình ký chữ ký điện tử sử dụng khoá công khai mô phỏng như ở hình 1.3, các bước thực hiện như sau:

55

Hình III.2.3 (1) - Sơ đồ quá trình ký vào tài liệu điện tử dùng khóa bí mật

Bước 1: Dùng giải thuật băm để thay đổi thông điệp cần truyền đi. Kết quả ta được một bản tin tóm lược1 (Message Digest). Dùng giải thuật băm SHA-1 để băm văn bản cần ký ta được bản mã có chiều dài cố định 160 bit.

Bước 2: Sử dụng giải thuật RSA cho quy trình ký văn bản, sử dụng khóa bí mật (Private key) của người gửi để Ký trên bản tin tóm lược thu được ở bước 1. Kết quả thu được gọi là “chữ ký điện tử”.

Bước 3: Gộp chữ ký điện tử vào bản tin điện tử ban đầu. Việc này gọi là “ký xác nhận” vào thông điệp. Sau khi đã ký xác nhận vào thông điệp, mọi sự thay đổi trên thông điệp sẽ bị phát hiện trong giai đoạn kiểm tra. Ngoài ra, việc ký xác nhận này đảm bảo người nhận tin tưởng thông điệp này xuất phát từ người gửi.

c. Xác thực chữ ký điện tử.

Dữ liệu sẽ gửi đi Bắt đầu

Văn bản cần ký Băm

Bản tin tóm lược1 Khóa bí mật

Chữ ký điện tử

Gắn chữ ký vào văn bản

56

Hình III.2.3 (2) - Sơ đồ quá trình xác thực điện tử dùng khóa công khai.

Sau khi nhận được một văn bản có đính kèm chữ ký của người gửi, người nhận văn bản phải giải mã trở lại văn bản trên và kiểm tra xem văn bản này đã bị thay đổi bởi một người thứ ba chưa, và chữ ký đính kèm trên văn bản có đúng của người gửi hay không (kiểm trachính danh”).

Quy trình xác nhận và kiểm tra thể hiện với các bước thực hiện như sau:

Bước 1: Bản tin điện tử có đính kèm chữ ký của người gửi, sau khi nhận sẽ được tách riêng phần chữ ký và phần văn bản nguyên vẹn. Sử dụng khóa công khai (Public

Kiểm tra. F T Bắt đầu Bản tin nhận được Tách văn bản và chữ ký Văn bản Chữ ký Băm Bản tin tóm lược2

Khóa công khai

Đúng người ký VB bị thay đổi

hoặc sai người ký. (adsbygoogle = window.adsbygoogle || []).push({});

57

key) của người gửi (khóa này được thông báo đến mọi người) để giải mã chữ ký điện tử của thông điệp, kết quả là “bản tin tóm lược”.

Bước 2: Dùng giải thuật băm SHA để băm văn bản đã tách phần chữ ký điện tử, kết quả thu được là “bản tin tóm lược thứ 2”.

Bước 3: Đầu vào kiểm tra chữ ký gồm bản tin tóm lược 2, chữ ký điện tử và khóa công khai của người gửi. Quá trình sẽ thực hiện dùng khóa công khai của người gửi giải mã chữ ký và so sánh với bản tin tóm lược 2, nếu hai kết quả này giống nhau ta kết luận được đúng người gửi, ngược lại văn bản không đúng người gửi hoặc văn bản đã bị sửa đổi.

3. Lựa chọn công cụ

- Ngôn ngữ lập trình web: C#, ASP, ASP.NET.

- Công cụ lập trình dịch vụ: Microsoft Visual Studio.

- Ngôn ngữ kịch bản: JavaScript, JQuery.

- Công cụ thiết kế báo cáo văn bản: DevExpress 2012.

- Hệ quản trị cơ sở dữ liệu: Microsoft SQL Server 2012.

- Tạo và quản lý khóa: Org.BouncyCastle, Microsoft ActiveX.

4. Cài đặt

4.1. Mô tả cài đặt

4.1.1. Mô tả cài đặt môi trường

* Các bộ cài chương trình cần có:

- Bộ cài Microsoft Visual Studio 2008.

58

- Thư viện Component hỗ trợ giao diện DevExpress 12.1.5

https://www.devexpress.com/Home/try.xml

* Các thư viện và chương trình hỗ trợ

- Org.BouncyCastle:

BouncyCastle là một dự án mã nguồn mở nhằm port thư viện tính toán số nguyên lớn và tính toán số nguyên tố cho chữ ký số RSA từ ngôn ngữ Java sang C#.NET. BouncyCastle không chỉ hỗ trợ việc tạo chữ ký số theo tiêu chuẩn PKCS#1 v1.5 và OAEP mà đây còn là một keystore có sẵn cho phép chúng ta lưu trữ các khóa vừa tạo trên máy chủ và kiểm tra đối chiếu sự hợp lệ của chúng như một hệ thống CA đơn giản.

Tải file thư viện dll và mã nguồn API của thư viện tại trang chủ https://www.bouncycastle.org/

- Thư viện ActiveX CAPICOM:

Do vấn đề bảo mật từ server side, browser không thể nhận biết được các thiết bị ngoại vi đang kết nối với máy client, để đọc được file .pfx trong smartcard, ta phải dùng thư viện ActiveX CAPICOM của Microsoft, nhược điểm là chỉ có thể sử dụng trên trình duyệt Internet Explorer 7.0 trở lên và trên các máy client cũng phải được cài đặt chương trình này.

CAPICOM là một thư viện ActiveX được Microsoft phát triển cho viện nhận diện các chứng thư số được cài đặt trong các thiết bị SmartCard hoặc USBKey khi người sử dụng dùng chúng để ký tại client

Download thư viện CAPICOM tại địa chỉ http://www.microsoft.com/vi- vn/download/details.aspx?id=25281

Copy 2 file dll download được vào thư mục C:\Windows\System32 và thực thi lệnh Command Line: “%systemroot%\System32\regsvr32 capicom.dll” để đăng ký chúng cho hệ điều hành.

59

Mở Interet Explorer > Option > Security > Custom level, tích chọn enable cho các option sau để cho phép thực thi software từ client: (adsbygoogle = window.adsbygoogle || []).push({});

- Allow ActiveX Filtering.

- Allow previous unused ActiveX controls to run without promt.

- Download Signed ActiveX controls.

- Initialize and script ActiveX controls not marked as safe for scripting (not secure)

- Run activeX controls and plugin.

4.1.2. Mô tả cài đặt chương trình

a. Tạo chứng chỉ X.509 với cặp khóa RSAKeyPair bằng thư viện Org.BouncyCastle

- Tạo class RsaKeyPairGenerator.cs để sinh cặp khóa RSA

Đầu vào: Tham số độ dài khóa (tối thiểu 512 bit)

Đầu ra: Cặp khóa RSA với các giá trị p,q,n,e,d,phi. (e được mặc định có giá trị 65535).

+ Khai báo tham số parameter đầu vào

private static readonly BigInteger DefaultPublicExponent =

BigInteger.ValueOf(0x10001);

private const int DefaultTests = 12;

private RsaKeyGenerationParameters param;

public void Init(

KeyGenerationParameters parameters)

{

60 {

this.param = (RsaKeyGenerationParameters)parameters;

}

else

{

this.param = new RsaKeyGenerationParameters(

DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests);

} }

+ Tạo cặp khóa RSA

public AsymmetricCipherKeyPair GenerateKeyPair() {

BigInteger p, q, n, d, e, pSub1, qSub1, phi;

// (adsbygoogle = window.adsbygoogle || []).push({});

// p and q values should have a length of half the strength in bits

//

int strength = param.Strength;

int pbitlength = (strength + 1) / 2;

int qbitlength = (strength - pbitlength);

int mindiffbits = strength / 3;

e = param.PublicExponent;

// TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)

// (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")

//

// Generate p, prime and (p-1) relatively prime to e //

for (; ; )

{

61

if (p.Mod(e).Equals(BigInteger.One))

continue;

if (!p.IsProbablePrime(param.Certainty))

continue;

if

(e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One))

break;

}

//

// Generate a modulus of the required length //

for (; ; )

{

// Generate q, prime and (q-1) relatively prime to e, // and not equal to p

//

for (; ; )

{ (adsbygoogle = window.adsbygoogle || []).push({});

q = new BigInteger(qbitlength, 1, param.Random);

if (q.Subtract(p).Abs().BitLength < mindiffbits)

continue;

if (q.Mod(e).Equals(BigInteger.One))

continue;

if (!q.IsProbablePrime(param.Certainty))

continue;

if

(e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One))

break;

62 //

// calculate the modulus //

n = p.Multiply(q);

if (n.BitLength == param.Strength)

break;

//

// if we Get here our primes aren't big enough, make the largest

// of the two p and try again // p = p.Max(q); } if (p.CompareTo(q) < 0) { phi = p; p = q; q = phi; }

pSub1 = p.Subtract(BigInteger.One);

qSub1 = q.Subtract(BigInteger.One);

phi = pSub1.Multiply(qSub1);

//

// calculate the private exponent //

d = e.ModInverse(phi);

//

// calculate the CRT factors //

BigInteger dP, dQ, qInv;

63 dQ = d.Remainder(qSub1); qInv = q.ModInverse(p);

return new AsymmetricCipherKeyPair(

new RsaKeyParameters(false, n, e), (adsbygoogle = window.adsbygoogle || []).push({});

new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ,

qInv)); } }

- Cài đặt chương trình tạo khóa

Từ thư viện lớp trên, ta tạo ra một cặp khóa RSA với độ dài 1024 bit, add chúng vào X509Store và xuất ra 2 file .pfx và .cer theo chuẩn X509

X509Store store = new X509Store(StoreName.My,

StoreLocation.CurrentUser);

store.Open(OpenFlags.MaxAllowed);

var kpgen = new RsaKeyPairGenerator();

kpgen.Init(new KeyGenerationParameters(new SecureRandom(new

CryptoApiRandomGenerator()), 1024));

var cerKp = kpgen.GenerateKeyPair();

IDictionary attrs = new Hashtable();

//attrs[X509Name.E] = "E-Mail";

attrs[X509Name.CN] = string.Format("{0}-{1}-{2}-{3}", txtHoTen.Text, d.ToString(), e.ToString(), n.ToString()); //attrs[X509Name.O] = "SIT";

//attrs[X509Name.C] = "TH";

IList ord = new ArrayList();

//ord.Add(X509Name.E);

ord.Add(X509Name.CN);

//ord.Add(X509Name.O); //ord.Add(X509Name.C);

64

X509V3CertificateGenerator certGen = new

X509V3CertificateGenerator();

certGen.SetSerialNumber(BigInteger.One);

certGen.SetIssuerDN(new X509Name(ord, attrs));

certGen.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0,

0, 0)));

certGen.SetNotAfter(DateTime.Today.AddDays(365));

certGen.SetSubjectDN(new X509Name(ord, attrs));

certGen.SetPublicKey(cerKp.Public);

certGen.SetSignatureAlgorithm("SHA1WithRSA"); (adsbygoogle = window.adsbygoogle || []).push({});

certGen.AddExtension(X509Extensions.BasicConstraints, true, new

BasicConstraints(false));

certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier,

true, new

AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicK eyInfo(cerKp.Public)));

Org.BouncyCastle.X509.X509Certificate x509 =

certGen.Generate(cerKp.Private);

System.Security.Cryptography.X509Certificates.X509Certificate

x509_ = DotNetUtilities.ToX509Certificate(x509.CertificateStructure);

X509Certificate2 x509__ = new X509Certificate2(x509_);

var privateKey =

(Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)cerKp.Pr

ivate;

var dotNetPrivateKey = ToDotNetKey(privateKey);

var dotNetCert = new

X509Certificate2(DotNetUtilities.ToX509Certificate(x509)); dotNetCert.PrivateKey = dotNetPrivateKey; byte[] cert_data = x509__.Export(System.Security.Cryptography.X509Certificates.X509Content Type.Cert); byte[] pvk_data = dotNetCert.Export(System.Security.Cryptography.X509Certificates.X509Con tentType.Pfx, txtMatKhau.Value);

65

FileStream fs = new

FileStream(string.Format("D:\\{0}.cer",txtHoTen.Text),

FileMode.CreateNew);

fs.Write(cert_data, 0, cert_data.Length); fs.Flush();

fs.Close();

FileStream fs2 = new FileStream(string.Format("D:\\{0}.pfx",

txtHoTen.Text), FileMode.CreateNew, FileAccess.ReadWrite);

fs2.Write(pvk_data, 0, pvk_data.Length); fs2.Flush();

fs2.Close();

BusinessLogic.TaoKhoa _TaoKhoa = new BusinessLogic.TaoKhoa();

_TaoKhoa.InsertHT_Khoa(txtHoTen.Text, txtMatKhau.Value,

CommonLib.ToDate(txtTuNgay.Text, "dd/MM/yyyy"), (adsbygoogle = window.adsbygoogle || []).push({});

CommonLib.ToDate(txtDenNgay.Text, "dd/MM/yyyy"), p, q, n, phi_n, e, d); store.Add(x509__);

store.Close();

Import các parameter được tạo ra vào khóa riêng:

public static AsymmetricAlgorithm

ToDotNetKey(Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParamete

rs privateKey)

{

var cspParams = new CspParameters

{

KeyContainerName = Guid.NewGuid().ToString(),

KeyNumber = (int)KeyNumber.Exchange,

Flags = CspProviderFlags.UseMachineKeyStore

};

var rsaProvider = new RSACryptoServiceProvider(cspParams);

var parameters = new RSAParameters

{ Modulus = privateKey.Modulus.ToByteArrayUnsigned(), P = privateKey.P.ToByteArrayUnsigned(), Q = privateKey.Q.ToByteArrayUnsigned(), DP = privateKey.DP.ToByteArrayUnsigned(), DQ = privateKey.DQ.ToByteArrayUnsigned(),

66 InverseQ = privateKey.QInv.ToByteArrayUnsigned(), D = privateKey.Exponent.ToByteArrayUnsigned(), Exponent = privateKey.PublicExponent.ToByteArrayUnsigned() }; rsaProvider.ImportParameters(parameters); return rsaProvider; }

Thực thi đoạn code trên sẽ tạo ra 2 file chứng chỉ số chứa thông tin về khóa:

Cặp khóa được lưu trong 2 file này dưới dạng một chuỗi xml: <RSAKeyValue> <Modulus>oqU9oC0BCBeqUSxJ7QBEYDu9e5Tshlc0zAupN/g+B1mAsDKeIi5X8yQr Z32R4Ul8BiAlIZfOIZ/eG8D48lAYcwNYQdWYQjPDJnXe4gV3Ga7Ys8StT3xdk2set0m4+BN c+/lppf8JHEeyxMc1L9dXJu33bETMmUL1D+trBnnLCcM=</Modulus> <Exponent>AQAB</Exponent> <P>77LXESDiMEfcxyckdAI5eH0XGnYnh7ATH4N/c2vzhPJnSf94Lp8JC6NhEK2N56 JQVvNqjE4NgZV/vZXpC2lfNQ==</P> <Q>rbTnRFwHsVDGufgYPEv7+qJ+MfaHvkDMzQo0mp/u3VJOrvaLhVmfXk0UVzRZdY pS0km5YJclSx0Xs6ZHwgkMFw==</Q> <DP>FQqU+IrzcBuO1OipuYlMdDg+4/LFS5L4SsbnVEGAsgX5bTSA307Uo3HnHmit0 UydUtSxYLmlU9/Ew+a5+2d3lQ==</DP> <DQ>V9v0TYMu8OSmX1G5EGZuYOrnYWYMapJkBCFxUfQq4Q7MdXqGP0CBdzUNYL49s VHxaiOX+973IfLpFhi4ms/wqQ==</DQ> <InverseQ>Hvh0bG7WFatl2JYG+K2/IYkmUplO+RWvbEPu6RNS/XDXfeGMNHeLzfT eHrI3Olep/SaB9FysPXxUaAG8mcIesg==</InverseQ> <D>Hld5MaJzqNDRYydB+0aretBqPt2/aihmnxIl1V0oJTLbQQOQYIwIuEEtH7dbOY 395x6kDqpFOByc0MylJH8wsCb2QXHqqAVcDOYfwnYqlLlXhYmldL3ydWHNJ69AUOWiw5xd9 g7O2O6ryybbYI/50m8m2UwczQ6Ow+73QcFPHvE=</D></RSAKeyValue>

File .cer chứa khóa công khai gồm exponent là e và modulus là n dùng để kiểm tra hoặc mã hóa được phân phát rộng rãi cho mọi người, file .pfx chứa khóa bí

67

mật dùng để ký hoặc giải mã nội dung được cấp cho người có trách nhiệm, muốn đọc được file .pfx cần biết mật khẩu để truy cập nội dung trong file.

Để đảm bảo hơn cho khóa bí mật trong file pfx, ta có thể nạp file này vào một thiết bị chứa khóa gọi là usb token key hoặc smartcard, người sử dụng không thể sao chép hoặc thay đổi khóa chứa trong này nếu không có mã PIN.

Hình III.4.1.2 – Hình ảnh minh họa một USB Key

Một phần của tài liệu Sử dụng chữ ký điện tử để xác thực trong quản lý công văn đi đến (Trang 54)