Tính này gây hệ quả nghiêm trọng trong trường hợp có lỗ hổng bảo mật dẫn đến làm giả thẻ tiền. Khi một đồng tiền được nạp thì không thể xác định là nó có bị làm giả. Thậm chí ngân hàng cũng không thể nhận ra các đồng tiền của chính mình làm ngăn chặn việc phát hiện giả mạo. Tức là việc vi phạm không thể bị phát hiện cho đến khi ngân hàng nhận thấy tổng lượng tiền nạp của tiền điện tử của họ lớn hơn lượng tiền mà được tạo bởi một khóa cụ thể. Lúc này thì sự mất mát có thể đã quá lớn.
Sau khi một sự giả mạo khóa bị phát hiện, ngân hàng vẫn không có khả năng phân biệt tiền có giá trị với tiền giả vì việc nạp tiền và rút tiền là không liên kết. Ngân hàng phải thay đổi khóa mật và hủy giá trị của tất cả các đồng tiền đã được ký với khóa đã bị đe dọa. Ngân hàng có thể thay thế các đồng tiền chưa được tiêu, nhưng giá trị của các đồng tiền không thể theo dấu đã dùng hoặc nạp không thể được quyết định mà không có sự hợp tác của người thanh toán. Thanh toán không tìm thấy dấu vết cản trở ngân hàng xác định định danh của người dùng, và sự nặc danh của người thanh toán cản trở người nhận thanh toán xác định người thanh toán.
Có thể giảm thiểu nguy cơ này bằng cách giới hạn lượng tiền bị ảnh hưởng bởi một lần tấn công đơn lẻ. Điều này có thể làm bằng cách thay đổi khóa công khai của ngân hàng sau một khoảng thời gian định trước, hoặc khi tổng giá trị của đồng tiền đã phát hành bởi một khóa vượt qua giá trị định trước. Tuy nhiên, kiểu làm này làm giảm tính
116 trang |
Chia sẻ: Dung Lona | Lượt xem: 1597 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Tìm hiểu về Tiền điện tử, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
n cần mã hĩa phải cĩ độ lớn nhỏ hơn tham số n của giải thuật Tuy nhiên ta cần mã hĩa các xâu cĩ độ dài bất kỳ nếu chuyển thành dạng mảng byte cũng là các mảng byte cĩ độ dài bất kỳ. Do đĩ thay vì chuyển xâu thàng dạng mảng byte một chiều, ta sẽ cắt xâu này thành các mảng byte liên tiếp cĩ độ dài khơng đổi (ví dụ 32 phần tử) như vậy xâu sẽ được biểu diễn thành mảng byte hai chiều. Quá trình biến đổi xâu như sau:xâu ký tự → mảng byte một chiều → mảng byte một chiều được cắt thành các mảng byte cĩ độ dài 32 tạo thành mảng byte 2 chiều.
Từng mảng byte cĩ độ dài 32 sẽ lần lượt được mã hĩa, cho kết quả là các mảng byte mã hĩa, mỗi mảng byte mã hĩa được chuyển sang dạng xâu Base64. Các xâu này sẽ được cộng với nhau theo thứ tự và cho kết quả là xâu mã hĩa trả về của dữ liệu.
Cài đặt cụ thể của từng hàm:
public string EncryptString(string sString,RSACryptoServiceProvider RSAProvider)
{
Int32 numberOfBlocks =( sString.Length / 32 ) + 1;
// chuyển xâu thành mảng byte 1 chiều
Char[] charArray = sString.ToCharArray();
// chuyển mảng byte 1 chiều thành mảng byte 2 chiều
Byte[][] byteBlockArray = new byte[ numberOfBlocks ][];
Int32 incrementer = 0;
for( Int32 i = 1; i <= numberOfBlocks; i++ )
{
if( i == numberOfBlocks )
{byteBlockArray[ i - 1 ] = Encoding.Unicode.GetBytes( charArray, incrementer, charArray.Length - incrementer );}
else
{
byteBlockArray[ i - 1 ] = Encoding.Unicode.GetBytes(charArray, incrementer, 32 );
incrementer += 32;
}
}
string sResult = "";
// mã hĩa
for( int j = 0; j < byteBlockArray.Length; j++ )
{
// chuyển mảng byte thành dạng xâu
sResult+= System.Convert.ToBase64String( RSAProvider.Encrypt( byteBlockArray[ j ], true ) ) ;
}
return sResult;
}
Hàm sau là hàm chồng hàm trên với tham số đầu vào là xâu dữ liệu cần mã hĩa và xâu biểu diễn thơng số khĩa cơng khai. Từ xâu biểu diễn khĩa ta sẽ tạo một đối tượng RSACryptoServiceProvider để làm tham số đầu gọi hàm EncryptString trên.
public string EncryptString(string sString,string sPubK)
{
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPubK);
return EncryptString(sString,RSAProvider);
}
Để giải mã các xâu đã mã hĩa bằng phương pháp trên em tạo hai hàm giải mã:
public string DecryptString ( string sString , RSACryptoServiceProvider RSAProvider ) giải mã xâu được mã hĩa sString bằng hàm EncryptString dùng đối tượng RSACryptoServiceProvider, hàm trả lại xâu đã giải mã.
public string DecryptString (string sString , string sPriK) giải mã giải mã xâu được mã hĩa sString bằng hàm EncryptString bằng khĩa mật cho bởi xâu sPriK, hàm trả lại xâu đã giải mã.
Để giải mã xâu ký tự ta chuyển xâu thành mảng byte, giải mã mảng byte đĩ bằng hàm Decrypt của lớp RSACryptoServiceProvider cho kết quả là mảng byte đã giải mã, mảng byte đĩ được chuyển thành xâu ký tự như là dữ liệu trả lại của phương thức. Vì hàm giải mã DecryptString giải mã xâu ký tự đã được mã hĩa bởi hàm EncryptString nên mảng byte sau khi giải mã phải giống với mảng byte được sinh ra sau khi biến đổi xâu ban đầu thành mảng byte trong hàm EncryptString.
Đối tượng RSACryptoServiceProvider được tạo bằng cách đọc thơng tin khĩa mật từ file khĩa mật *.kez.
Dạng của xâu được mã hĩa là các xâu mã hĩa liên tiếp, các xâu này được biến đổi các từ mảng byte được mã hĩa trong hàm EncryptString nên để giải mã ta sẽ cắt xâu cần giải mã thành các xâu con ban đầu, biến đổi các xâu con đĩ thành các mảng byte, giải mà lần lượt từng mảng byte này và ghép chúng lại thành mảng byte duy nhất. Từ mảng byte duy nhất đĩ ta chuyển đổi nĩ thành dạng xâu ký tự và được xâu đã giải mã.
Sau đây là cài đặt cụ thể của từng hàm
public string DecryptString(string sString,RSACryptoServiceProvider RSAProvider )
{
string encryptedBlock = "";
System.Collections.Queue encryptedBlocks = new System.Collections.Queue();
while( sString.Length != 0 )
{
if( RSAProvider.KeySize==1024 )
{
encryptedBlock = sString.Substring( 0, sString.IndexOf( "=" ) + 1 );
encryptedBlocks.Enqueue( encryptedBlock );
sString = sString.Remove( 0, encryptedBlock.Length );
}
else
{
encryptedBlock = sString.Substring( 0, sString.IndexOf( "==" ) + 2 );
encryptedBlocks.Enqueue( encryptedBlock );
sString = sString.Remove( 0, encryptedBlock.Length );
}
}
encryptedBlocks.TrimToSize();
Int32 numberOfBlocks = encryptedBlocks.Count;
string sResult ="";
for( Int32 i = 1; i <= numberOfBlocks; i++ )
{
encryptedBlock =( System.String )encryptedBlocks.Dequeue();
sResult+=( Encoding.Unicode.GetString( RSAProvider.Decrypt( System.Convert.FromBase64String( encryptedBlock ), true) ) ); }
return sResult;
}
Hàm sau là hàm chồng hàm trên với đối số là xâu cần giải mã và xâu chứa thơng tin khĩa mật RSA. Từ xâu chứa thơng tin khĩa mật RSA ta tạo đối tượng RSACryptoProvider và gọi hàm trên.
public string DecryptString(string sString,string sPubK)
{
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPubK);
return DecryptString(sString,RSAProvider);
}
Ví dụ mã hĩa giải mã:
Mã hĩa bằng khĩa cơng khai RSA 1024 bit:
Giải mã bằng khĩa mật RSA tương ứng:
Tạo chữ ký và kiểm tra chữ ký RSA
Lớp RSACryptoServiceProvider cung cấp phương thức sau để sinh chữ ký và kiểm tra chữ ký:
public byte[] SignData ( byte[] buffer , System.Object halg ) tính giá trị băm của mảng byte buffer với giải thuật băm cho bởi halg và ký lên kết quả băm, chữ ký trả lại cũng ở dạng mảng byte.
public bool VerifyData ( byte[] buffer , System.Object halg , byte[] signature ) kiểm tra chữ ký của dữ liệu buffer với hàm băm halg, với chữ ký signature, nếu đúng trả lại gái trị true, nếu sai trả lại false.
Khĩa mật RSA cĩ thể lấy từ file chứa khĩa mật *.kez. Trước khi ký ta cần chuyển xâu văn bản thành dạng mảng byte để cĩ thể dùng hàm SignData.
Sau đây các hàm tạo chữ ký cho một xâu ký tự:
public string SignData(string sText,RSACryptoServiceProvider RSAprovider)
{
// chuyển xâu ký tự thành mảng byte
byte[] bText = Encoding.Unicode.GetBytes(sText);
// giải thuật băm
MD5CryptoServiceProvider objMD5 = new MD5CryptoServiceProvider();
// tạo chữ ký
byte[] bSign = RSAprovider.SignData(bText,objMD5);
// trả lại chữ ký dưới dạng base64
return Convert.ToBase64String(bSign);
}
public string SignData(string sText,string sPriKB)
{
// tạo đối tượng RSACryptoProvider bằng thơng tin khĩa mật sPriKB
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPriKB);
// gọi hàm SignData với đối số là đối tượng
// RSACryptoServiceProvider
return SignData(sText, RSAProvider);
}
Để kiểm tra chữ ký ta cần văn bản gốc, chữ ký, giải thuật băm dùng để ký và khĩa cơng khai tương ứng với khĩa mật dùng để ký. Hàm kiểm tra chữ ký sau sẽ kiểm tra chữ ký dạng xâu ký tự của một xâu ký tự bằng khĩa cơng khai cho bởi xâu sPubK. Hàm trả về giá trị true nếu chữ ký hợp lệ và false nếu khơng.
public bool CheckSign(string sText,string sSign,string sPKA)
{
// tạo đối tượng RSACrytoServiceProvider để kiểm tra
// chữ ký
RSACryptoServiceProvider RSAprovider = new RSACryptoServiceProvider();
RSAprovider.FromXmlString(sPKA);
// chữ ký và văn bản gốc
byte[] bSign = Convert.FromBase64String(sSign);
byte[] bText = Encoding.Unicode.GetBytes(sText);
// giải thuật băm sử dụng
MD5CryptoServiceProvider objMD5 = new MD5CryptoServiceProvider();
return RSAprovider.VerifyData(bText,objMD5,bSign);
}
Tạo số biểu diễn số tiền rút và thời hạn
Vì số v biểu diễn số tiền rút và thời hạn cĩ dạng
dd/mm/yyyy (Ngày hết hạn)
$xxx.xx (Số tiền)
Nên em sẽ tạo một số v cĩ dạng là xxxddmmyyyy, trong đĩ xxx là số tiền, ddmmyyyy tạo thành dd/mm/yyyy là ngày hết hạn (dd là ngày, mm là tháng, yyyy là năm). Số v phải thỏa mãn tính chất là tìm được số v’ sao cho mod n với mọi a (để ta cĩ thể tính được β ≡ ), ta thấy tính chất này tương tự với cặp số mũ mật và cơng khai của giải thụật RSA là d và e.
Thật vậy giả sử M là văn bản được mã hĩa bằng khĩa cơng khai (e, n)
C
Từ C ta cĩ thể giải mã ra M bằng khĩa mật (d, n)
M
Do tính chất ((a mod n) * (b mod n)) mod n (a * b) mod n
Nên M
Mà d và e cĩ quan hệ de 1 mod (p – 1)(q – 1) hay e d – 1 mod (p – 1)(q – 1) và e được gọi là nghịch đảo modulo của d.
Vậy số v phải được tạo sao cho tồn tại nghịch đảo mod (pb – 1)(qb – 1) của nĩ. Vì chỉ cĩ ngân hàng là biết các tham số mật pb, qb nên buộc phải cĩ sự tham gia của ngân hàng trong việc tạo số v này.
Để tạo số v khách hàng sẽ truy cập vào trang web của ngân hàng và yêu cầu tạo số biểu diễn số tiền rút và thời hạn v. Khách hàng sẽ được yêu cầu nhập các thơng tin cá nhân (IDA) đã đăng ký với ngân hàng, để tránh các trường hợp người dùng cĩ mục đích khơng tốt mà khơng bị kiểm sốt. Khách hàng sẽ chọn số tiền định rút (xxx) và thời hạn cho tiền điện tử sẽ tạo (dd/mm/yyyy) và tạo thành số v = xxxddmmyyyy. Nhưng khơng phải số v nào ở dạng này cũng tồn tại nghịch đảo (mod (pb – 1)(qb – 1)) nên số v thực sự được tạo cĩ dạng v = xxxddmmyyyy? trong đĩ ? cĩ thể là số nguyên từ 1, 2, 3, 4 ….cho đến khi nào thỏa mãn với v thì tồn tại nghịch đảo của v.
Việc xuất các tham số mật p. q của khĩa mật RSA của ngân hàng ta làm tương tự như cách xuất các tham số giải thuật RSA ở trên: đọc xâu chứa nội dung mật của giải thuật RSA từ file khĩa mật *.kez, tạo đối tượng RSACryptoServiceProvider từ xâu này, và từ đối tượng RSACryptoServiceProvider xuất ra đối tượng RSAParameters chứa các tham số cần lấy.
Sau khi đã cĩ các tham số pb, qb ta cần phải tính (pb – 1)(qb – 1) để tính tốn với các số nguyên tố lớn ta dùng lớp BigInteger. Hai đối tượng lớp BigInteger được tạo tương ứng với giá trị pb, qb và một đối tượng BigInteger biểu diễn số nguyên giá trị là 1. Và ta sẽ tính được = (pb – 1)(qb – 1) như sau:
Ta sẽ thử các giá trị của v từ xxxddmmyyyy đến xxxddmmyyyy1, xxxddmmyyyy2, xxxddmmyyyy3 … cho đến khi tồn tại nghịch đảo của v tính bằng hàm modInverse
// hàm tạo số v từ số tiền rút và thời hạn
public string CreateV(string sSotien,string sThoihan,string sPriKB)
{
// khởi tạo số v
string sV = sSotien+sThoihan;
BigInteger objNum = new BigInteger(sV,10);
// xuất thơng tin khĩa mật
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPriK);
RSAParameters RSAPara = RSAProvider.ExportParameters(true);
byte[] bArrayP = RSAPara.P;
byte[] bArrayQ = RSAPara.Q;
// khởi tạo các số nguyên lớn
BigInteger objP = new BigInteger(bArrayP);
BigInteger objQ = new BigInteger(bArrayQ);
BigInteger objOne = new BigInteger(1);
// tính (pb – 1) * (qb – 1)
BigInteger objPhiN = (objP-objOne )*(objQ-objOne);
// chọn v phù hợp
int i = 0;
while (true)
{
try
{
BigInteger objTemp = bjNum.modInverse(objPhiN);
return objNum.ToString();
}
Catch
{
i++;
string sTemp = sNumber + i;
objNum = new BigInteger(sTemp,10);
}
}
}
Ví dụ về một số v được tao ra theo cách này là: 200050720061 thì số tiền rút ra là 200000 đồng, ngày hết hạn là 05/07/2006.
Giao diện của form đăng ký tạo số biểu diễn số tiền rút và thời hạn
Số thời hạn được lưu ở file cĩ phần mở rộng là *.sov
Tạo đơn đăng ký tiền điện tử
Sau khi đã cĩ số v biểu diễn số tiền rút và thời hạn, khách hàng cĩ thể tạo đơn đăng ký tiền số cĩ giá trị và thời hạn như trong số v. Các thơng tin khách hàng cần đưa vào trong quá trình tạo đăng ký tiền điện tử là
IDA hay là định danh của khách hàng
AccountA tài khoản của khách tại ngân hàng
TimeA nhãn thời gian của đơn đăng ký
Khĩa cơng khai (et, nt) của cặp khĩa RSA tạm thời được tạo mỗi lần rút tiền.
Ngồi ra khách hàng cần tính α ≡ trong đĩ v là số tiền và thời hạn cần rút, r là hệ số mù được sinh ngẫu nhiên bởi khách hàng., H() là hàm băm thích hợp và (eb, nb) là khĩa cơng khai của ngân hàng. s ≡ (r-1β mod nb), tức là r phải tồn tại nghịch đảo của r mod nb.
Sinh hệ số mù ngẫu nhiên
Ta cần sinh một số nguyên ngẫu nhiên cho hệ số mù r, tuy nhiên sau khi ngân hàng đã ký vào văn bản mù α thì để sinh chữ ký thực sự của ngân hàng ta phải triệt tiêu hệ số mù r này bằng phép tính s ≡ (r-1β mod nb).
Tuy nhiên các số nguyên ngẫu nhiên được sinh ra khơng phải số nào cũng tồn tại nghịch đảo nên khi khách hàng tạo hệ số mù phải thử cho đến khi nào số ngẫu nhiên này thỏa mãn điều kiện tồn tại nghịch đảo mod nb (nb là tham số khĩa cơng khai của ngân hàng).
Ta cĩ thể dùng lớp BigInteger để biểu diễn số nguyên lớn nb (độ dài tối thiểu 1024 bit) và tính nghịch đảo mod nb của r.
// tạo đối tượng big Integer biểu diễn giá trị nb xuất ra từ đối tượng // RSAParameters
BigInteger objNB = new BigInteger(bArrayNB);
// tìm cho đến khi tồn tại nghịch đảo của r
while (true)
{
Random ran = new Random();
string sInteger = ran.Next(int.MaxValue).ToString();
try
{
BigInteger objRan = new BigInteger(sInteger,10);
BigInteger objTemp = objRan.modInverse(objNB);
break;
}
catch
{
}
}
Tạo yêu cầu rút tiền
Yêu cầu rút tiền được tạo bởi khách hàng bao gồm: IDA, AccountA, PKA, α, v, TimeA, signA trong đĩ signA là chữ ký của khách hàng trên văn bản.
IDA là định danh của khách hàng gồm các thơng tin cá nhân.
AccountA biểu diễn tài khoản của khách hàng tại ngân hàng, AccountA cĩ thể là số tài khoản và mã số tài khoản.
PKA là khĩa cơng khai của khách hàng.
TimeA là nhãn thời gian.
v là số biểu diễn số tiền rút và thời hạn được tạo ra như ở trên.
Ta cần tính α ≡ ,
trong đĩ (et, nt) là khĩa cơng khai tạm thời tạo bởi khách hàng
(eb, nb) là khĩa cơng khai của ngân hàng. được lấy từ chứng chỉ khĩa cơng khai của ngân hàng.
r là số nguyên ngẫu nhiên, được tạo ra như ở trên
H() là hàm băm, || là phép ghép.
Để tạo số α trước hết ta cần tọa cặp khĩa RSA tạm thời, ta sẽ dùng mơđun tạo khĩa ở trên. Sau khi đã tạo được căp khĩa này ta sẽ lấy các tham số khĩa cơng khai là et, nt để tính H(et||nt). Khĩa cơng khai của ngân hàng cĩ thể lấy từ chứng chỉ khĩa cơng khai của ngân hàng, từ đĩ ra cĩ thể tính ra α.
Dữ liệu et, nt sẽ được biểu diễn dưới dạng mảng byte nên phép ghép đơn giản sẽ là nối hai mảng byte thành một mảng byte. Hàm ghép hai mảng byte:
// ghép hai mảng byte bArray1 = {b1[0],..., b1[n]} và bArray2 =
// {b2[0],..., b2[m]} thành 1 mảng byte {b1[0],..., b1[n], b2[0],..., // b2[m]}
public byte[] ConcatByteArrays(byte[] bArray1,byte[] bArray2)
{
int iLength = bArray1.Length+bArray2.Length;
byte[] bTemp = new byte[iLength];
for (int i=0;i<iLength;i++)
{
if (i < bArray1.Length) bTemp[i] = bArray1[i];
else bTemp[i] = bArray2[iLength - 1 - i];
}
return bTemp;
}
Ta cĩ
α ≡
Hàm tính α sau nhận đầu vào là các số v, r dạng thập phân, các thơng số khĩa cơng khai tạm thời và khĩa cơng khai của ngân hàng. Số α trả lại dưới dạng thập phân.
public string CreatAlpha(string v,string PKT,string PKB,string r)
{
// tính (r^(eb*v) mod nb)
BigInteger objV = new BigInteger(v,10);
BigInteger objR = new BigInteger(r,10);
// xuất thơng tin khĩa cơng khai ngân hàng (eb, nb)
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(PKB);
RSAParameters RSAPara = RSAProvider.ExportParameters(false);
byte[] bArrayNB = RSAPara.Modulus;
byte[] bArrayEB = RSAPara.Exponent;
BigInteger objNB = new BigInteger(bArrayNB);
BigInteger objEB = new BigInteger(bArrayEB);
BigInteger objResult1 = objR.modPow(objV,objNB);
objResult1 = objResult1.modPow(objEB,objNB);
// tính H(et||nt) mod nb
// xuất thơng tin khĩa cơng khai tạm thời(et, nt)
RSAProvider.FromXmlString(PKT);
RSAPara = RSAProvider.ExportParameters(false);
byte[] bArrayNT = RSAPara.Modulus;
byte[] bArrayET = RSAPara.Exponent;
byte[] bConcat = bjByteArray.ConcatByteArrays(bArrayET,bArrayNT);
// giải thuật băm
MD5CryptoServiceProvider MD5Provider = new MD5CryptoServiceProvider();
byte[] bHash = MD5Provider.ComputeHash(bConcat);
BigInteger objHash = new BigInteger(bHash);
BigInteger objResult2 = objHash % objNB;
// tính alpha
BigInteger objResult = objResult1 * objResult2;
objResult = objResult % objNB;
return objResult.ToString();
}
Khi đã tính được α khách hàng đã cĩ thể tạo được văn bản yêu cầu rút tiền IDA, AccountA, PKA, α, v, TimeA và khách hàng sẽ ký văn bản này bằng khĩa mật của mình. Khĩa cơng khai và khĩa mật được đọc từ các file chứa khĩa cơng khai (*.pke) và khĩa mật (*.kez) tương ứng.
// văn bản cần ký
string sData = sIDA +’,’ + sAccountA + ’,’ + sPubKA + ’,’ + sAlpha + ’,’ + sV + ’,’+ sTimeA;
// ký văn bản với hàm SignData
string sSign = SignData(sData,sPriKA);
Theo giao thức gốc thì văn bản này cộng với chữ ký sẽ được gửi đến ngân hàng qua kênh mật SSL để đảm bảo tính bảo mật. Vì thơng tin về tài khoản là các thơng tin mật và rất nhạy cảm, nếu một ai đĩ biết được thơng tin này thì tài khoản của khách hàng tại ngân hàng sẽ bị mất. Vì vậy thay vì gửi văn bản dưới dạng rõ ràng này cho ngân hàng, khách hàng cĩ thể mã hĩa văn bản bằng khĩa cơng khai của ngân hàng. Vì chỉ cĩ ngân hàng là biết khĩa mật của ngân hàng nên chỉ cĩ ngân hàng là giải mã được nĩ. Do đĩ ngay cả khi văn bản này rơi vào tay người khác thì họ cũng khơng thể biết được thơng tin tài khoản của khách hàng.
Khĩa cơng khai của ngân hàng sẽ được lấy từ chứng chỉ khĩa cơng khai của ngân hàng như trong phần trên.
Ta sẽ tạo yêu cầu rút tiền gửi ngân hàng như sau:
string sOrder = ""+sData+""+sSign+"";
// mã hĩa bằng khĩa cơng khai của ngân hàng
sOrder= EncryptString(sOrder,sPubKB);
sOrder = "" + sOrder+"";
// tạo file
CreateFileText(filename,sOrder);
Yêu cầu rút tiền sẽ được lưu ở file cĩ phần mở rộng là *.odc.
Giao diện form tạo yêu cầu rút tiền
Nhận yêu cầu rút tiền
Sau khi khách hàng đã cĩ yêu cầu rút tiền khách hàng sẽ gửi yêu cầu này tới ngân hàng kèm với chứng chỉ khĩa cơng khai của mình. Ngân hàng nhận được yêu cầu sẽ giải mã yêu cầu bằng khĩa mật của ngân hàng, sau đĩ kiểm tra chữ ký của khách hàng bằng khĩa cơng khai của khách hàng.
...
// đọc khĩa cơng khai của khách hàng
string sPubKA = objCrypto.GetPublicKeyFromCert(sPath+"/"+sFileCert);
// lấy khĩa mật ngân hàng
string sPriKB = objAccount.SelectDefaultPrivateKey();
// đọc nội dung yêu cầu rút tiền
clsXML objXML = new clsXML(sPath+"/"+sFileName);
string sContent = objXML.GetXmlNodeContent("/OrderDigiCash");
// giải mã yêu cầu rút tiền
try
{
sContent = objCrypto.DecryptString(sContent,sPriKB);
}
catch
{
lblThongbao.Text="Dữ liệu khơng hợp lệ";
return;
}
// kiểm tra chữ ký
if (CheckSign(sData,sSign,sPKA))
{
// tiếp tục việc rút tiền
...
Sau đĩ ngân hàng kiểm tra định danh định danh, tài khoản và nhãn thời gian của văn bản. Nếu tất cả hợp lệ ngân hàng kiểm tra số v để xem số tiền cần rút và thời hạn, sau đĩ ngân hàng trừ trong tài khoản của khách hàng một lượng tiền tương ứng và gửi lại văn bản sau cho khách hàng: IDA, IDB, β, TimeB, signB.
Trong đĩ: IDA là định danh của khách hàng
IDB là định danh của ngân hàng
TimeB là nhãn thời gian
β ≡
signB là chữ ký của ngân hàng trên văn bản IDA, IDB, β, TimeB.
Để tính β cĩ α và khĩa mật của ngân hàng. Vì tính với vv’ ≡ 1 (mod (pb – 1) (qb – 1)) trong đĩ pb, qb là các tham số mật của giải thuật RSA của ngân hàng.
Ta cĩ hàm tính β với đầu vào là số α và số v dưới dạng thập phân và khĩa mật của ngân hàng, hàm trả lại số β dưới dạng thập phân.
public string CreatBeta(string sAlpha,string sV,string sPriKB)
{
// khởi tạo alpha và v
BigInteger objAlpha = new BigInteger(sAlpha,10);
BigInteger objV = new BigInteger(sV,10);
// lấy các tham số db và nb
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPriKB);
RSAParameters RSAPara = RSAProvider.ExportParameters(true);
byte[] bArrayDB = RSAPara.D;
byte[] bArrayNB = RSAPara.Modulus;
BigInteger objDB = new BigInteger(bArrayDB);
BigInteger objNB = new BigInteger(bArrayNB);
// tính nghịch đảo của v
byte[] bArrayP = RSAPara.P;
byte[] bArrayQ = RSAPara.Q;
BigInteger objP = new BigInteger(bArrayP);
BigInteger objQ = new BigInteger(bArrayQ);
BigInteger objOne = new BigInteger(1);
BigInteger objPhiN = (objP-objOne )*(objQ-objOne);
BigInteger objInverseV = objV.modInverse(objPhiN);
// tính Beta = ((α ^ db mod nb) * (α ^ inverseV mod nb)) mod nb
BigInteger objResult = objAlpha.modPow(objDB,objNB);
objResult = objResult.modPow(objInverseV,objNB);
return objResult.ToString();
}
Sau khi đã tính được β ngân hàng cĩ thể tạo văn bản trả lời rút tiền cho khách: : IDA, IDB, β, TimeB và ký văn bản này bằng khĩa mật của ngân hàng cho chữ ký signB. Để đảm bảo tính bảo mật ngân hàng cĩ thể mã hĩa văn bản này bằng khĩa cơng khai của khách hàng để chỉ cĩ khách hàng đọc được thơng tin này. Văn bản sẽ được lưu ở file cĩ phần mở rộng là *.rod. (Văn bản gửi cho khách hàng vẫn được truyền qua kênh mật SSL).
...
// tạo văn bản trả lời
string sDataB = sIDA+','+ sIDB +','+ sBeta +',' + sTimeB;
// tạo chữ ký cho văn bản
string sSignB =SignData(sDataB,sPriKB);
string sReturn = ""+sDataB+""+sSignB+"";
sReturn = objCrypto.EncryptString(sReturn,sPubKA);
sReturn = ""+sReturn+"";
CreateFileText(FileName,sReturn);
...
Giao diện form nhận yêu cầu rút tiền
Tạo tiền điện tử
Khi khách hàng nhận được trả lời của ngân hàng, khách hàng sẽ giải mã nĩ bằng khĩa mật của mình và tạo tiền điện tử bằng cách tính s ≡ (r-1β mod nb) như là chữ ký mù của ngân hàng.
Để tính s khách hàng cần cĩ β, và khĩa cơng khai của ngân hàng. Để tiện cho việc tính tốn ta cĩ thể biến đổi như sau s ≡ (r-1β mod nb) ≡ ((r-1 mod nn) * (1β mod nn)) mod nn, trong đĩ (r-1 mod nn) chính là nghịch đảo mod nb của r.
Hàm tính s sau nhận r, β là các tham số vào dưới dạng thập phân, khĩa cơng khai ngân hàng cho bởi xâu, hàm trả lại số s dưới dạng thập phân.
public string CreatS(string sSoR,string sPKB,string sBeta)
{
// khởi tạo r và beta
BigInteger objR = new BigInteger(sSoR,10);
BigInteger objBeta = new BigInteger(sBeta,10);
// lấy tham số nn của khĩa cơng khai ngân hàng
RSACryptoServiceProvider RSAprovider = new RSACryptoServiceProvider();
RSAprovider.FromXmlString(sPKB);
RSAParameters RSAPara = RSAprovider.ExportParameters(false);
byte[] bArrayNB = RSAPara.Modulus;
//bArrayNB =objByteArray. ReverseByteArray(bArrayNB);
BigInteger objNB = new BigInteger(bArrayNB);
// tính nghịch dảo của r
BigInteger objInverseR = objR.modInverse(objNB);
// tính s
BigInteger objResult = (objInverseR * (objBeta % objNB)) % objNB;
return objResult.ToString();
}
Sau khi đã cĩ s khách hàng đã cĩ thể tạo tiền số cĩ dạng (et, nt, v, s).
Giao diện form tạo tiền số:
Mua hàng và thanh tốn trực tuyến
Giao thức:
A → ES: E-goods, Cost, AccountES, et, nt, v, s, TimeA, signt
ES → B: Cost, AccountES, et, nt, v, s, TimeA, EMD, signt
B → ES: ReceiptES, et, nt, v, s, RM, s', TimeB, signB
ES → A: License, ReceiptA, et, nt, v, s, RM, s', TimeES, signES
Giả sử khách hàng vào trang web của người bán hàng, sau khi xem một số mặt hàng khách hàng quyết định chọn mua số hàng hĩa của cửa hàng, thì cửa hàng sẽ gửi một hĩa đơn cĩ dạng E-goods, Cost cho khách hàng trong đĩ E-goods là các mặt hàng khách hàng đặt mua, cost là giá của các hàng này.
Tạo đơn thanh tốn hĩa đơn
Sau khi nhận hĩa đơn khách hàng sẽ tính một đơn thanh tốn hĩa đơn và gửi cho cửa hàng. Thanh tốn hĩa đơn đĩ cĩ dạng E-goods, Cost, et, nt, v, s, TimeA
trong đĩ
E-goods, Cost là hĩa đơn,
(et, nt, v, s) là tiền điện tử của khách hàng,
TimeA là nhãn thời gian
Khách hàng sẽ ký vào văn bản bằng khĩa mật tạm thời rồi gửi E-goods, Cost, et, nt, v, s, TimeA, signt
...
// lấy thơng tin hĩa đơn
string sProductAndPrice = ReadToEndFile(billFileName);
// lấy thơng tin khĩa mật tạm thời
string sPriKT = ReadToEndFile(tempPriKey);
// lấy thơng tin tiền số
clsXML objXML = new clsXML(sECashPath);
string sPubKT = objXML.GetXmlNodeContent("/ECash/PKT");
string sV = objXML.GetXmlNodeContent("/ECash/V");
string sS= objXML.GetXmlNodeContent("/ECash/S");
// tạo thanh tốn hĩa đơn và chữ ký
string sData = sProductAndPrice+','+sPubKT+','+sV+','+sS++','+sTimeA;
string sSign = SignData(sData,sPriKT);
CreateFile(saveFileDialog1.FileName,"Order",sData,sSign);
...
Thanh tốn hĩa đơn được tạo lưu ở file cĩ phần mở rộng là *.pob.
Giao diện form tạo thanh tốn hĩa đơn:
Nhận thanh tốn hĩa đơn
Khách hàng sau tạo thanh tốn hĩa đơn sẽ gửi cho cửa hàng. Cửa hàng sẽ kiểm tra chữ ký signt trên văn bản cĩ phù hợp bằng khĩa cơng khai (et, nt) trong văn bản. Sau đĩ cửa hàng kiểm tra hàng và giá cả cĩ phù hợp, nếu phù hợp thì kiểm tra đến tiền điện tử của khách hàng. Cửa hàng kiểm tra tiền điện tử bằng cách xem liệu cĩ thỏa mãn.
Để kiểm tra được điều này cửa hàng cần cĩ khĩa cơng khai của ngân hàng (ở dạng chứng chỉ khĩa cơng khai), tiền điện tử (et, nt, v, s) của khách hàng.
Hàm kiểm tra tính hợp lệ của tiền điện tử sau nhận các đối số v, s dưới dạng các số thập phân, các xâu biểu diễn khĩa cơng khai tạm thời và khĩa cơng khai của ngân hàng .
public bool CheckECash(string sV,string sS,string sPubKT,string sPubKB)
{
// đọc thơng tin khĩa cơng khai ngân hàng
clsByteArray ByteArray = new clsByteArray();
RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider();
RSAProvider.FromXmlString(sPubKB);
RSAParameters RSAPara = RSAProvider.ExportParameters(false);
byte[] bNB = RSAPara.Modulus;
BigInteger objNB = new BigInteger(bNB);
byte[] bEB = RSAPara.Exponent;
BigInteger objEB = new BigInteger(bEB);
// đọc thơng tin khĩa cơng khai tạm thời
RSAProvider.FromXmlString(sPubKT);
RSAPara = RSAProvider.ExportParameters(false);
byte[] bArrayNT = RSAPara.Modulus;
byte[] bArrayET = RSAPara.Exponent;
byte[] bConcat = ByteArray.ConcatByteArrays(bArrayET,bArrayNT);
// tính H(et ||nt) mod nb
MD5CryptoServiceProvider MD5Provider = new MD5CryptoServiceProvider();
byte[] bHash = MD5Provider.ComputeHash(bConcat);
BigInteger objResult1 = new BigInteger(bHash);
objResult1 = objResult1 % objNB;
// tính s ^ (eb*v)
BigInteger objS = new BigInteger(sS,10);
BigInteger objV = new BigInteger(sV,10);
BigInteger objResult2 =objS.modPow(objEB,objNB);
objResult2=objResult2.modPow(objV,objNB);
// so sánh hai kết quả
return (objResult1.ToString()==objResult2.ToString());
}
Nếu tất cả các thơng tin trên đều được thỏa mãn cửa hàng sẽ gửi tới ngân hàng yêu cầu thanh tốn cĩ dạng như sau: Cost, AccountES, et, nt, v, s, TimeA, EMD, signt tức là hồn tồn tương tự với nội dung thanh tốn hĩa đơn của khách hàng gửi cho cửa hàng, cộng thêm với thơng tin tài khoản của cửa hàng. Thơng tin này sẽ được mã hĩa bằng khĩa cơng khai của ngân hàng để đảm bảo chỉ cĩ ngân hàng là đọc được nĩ.
Vì hệ thống là thanh tốn trực tuyến nên cửa hàng cần phải đưa chi tiết thanh tốn cho ngân hàng trước khi chấp nhận thanh tốn và giao hàng cho khách. Cĩ nhiều cách để đưa cho ngân hàng các thơng tin này, nhưng ở đây em thiên về giải pháp dùng Web service. Tức là ngân hàng sẽ cung cấp cho cửa hàng một web service, mỗi khi cửa hàng cần thực hiện thanh tốn chỉ cần gọi web service này.
Web Service thực hiện thanh tốn
Trong C# để dùng một web service ta cần biết địa chỉ url của nĩ và chỉ cần thêm nĩ vào như một Web Reference, đặt cho nĩ một tên cụ thể, Một web reference cung cấp cho ta một lớp với giao diện là các thuộc tính và phương thức cĩ trong web service. Để dùng các phương thức hay thuộc tính này ta cần khai báo một đối tượng lớp đĩ.
Ví dụ nếu ngân hàng cĩ Web Servie là CheckECash, một cửa hàng cĩ thể dùng web service bằng cách thêm nĩ vào như một web reference và đặt tên là BankService, mỗi khi cửa hàng cần dùng các dịch vụ cĩ trong Web Service của ngân hàng, cửa hàng chỉ cần tạo một đối tượng như sau:
BankService.CheckECash service = new BankService.CheckECash();
Và gọi phương thức của đối tượng đĩ để thực hiện giao dịch
string sResult = service.CheckDigiCash(sAccountB,sData,sSign);
Phương thức mà ngân hàng tạo ra trong Web Servie của mình là:
[WebMethod] // web method để chỉ đây là hàm cĩ thể gọi bằng web service
public string CheckDigiCash(string sAccount,string sData,string sSign)
hàm này nhận tham sĩ là tài khoản của cửa hàng, thanh tốn hĩa đơn của khách hàng cùng với chữ ký tạo bởi khĩa mật tạm thời.
Ngân hàng sau khi nhận các thơng tin này sẽ kiểm tra chữ ký và dữ liệu xem cĩ phù hợp; nếu chúng phù hợp, ngân hàng sẽ lấy thơng tin tiền điện tử từ thanh tốn hĩa đơn của khách hàng và kiểm tra sự hợp lệ của tiền điện tử, kiểm tra giá trị của tiền cĩ đủ để thanh tốn. Nếu lượng tiền này là đủ ngân hàng sẽ nạp thêm tiền vào tài khoản cho cửa hàng, đồng thời thêm tiền vào cơ sở dữ liệu tiền đã tiêu. Sau đĩ ngân hàng gửi lại cho cửa hàng thơng báo và tiền cịn lại của khách hàng sau thanh tốn.
Vì để đảm bảo tính bảo mật thơng tin tài khoản của cửa hàng đã được cửa hàng mã hĩa bằng khĩa cơng khai của ngân hàng nên chỉ cĩ ngân hàng mới cĩ thể giải mã được thơng tin này.
[WebMethod]
public string CheckDigiCash(string sAccount,string sData,string sSign)
{
// lấy thơng tin khĩa
string sPubKT = ... // khĩa cơng khai tạm thời
string sPriKB = ... // khĩa mật của ngân hàng
// kiểm tra chữ ký
if (!CheckSign(sData,sSign,sPubKT))
{
return ... // trả lại thơng báo khơng thành cơng nếu
// chữ ký khơgn hợp lệ
}
// giải mã thơng tin tài khoản của
string sAccountES = DecryptString(sAccount,sPriKB);
// kiểm tra tài khoản của cửa hàng
...
// kiểm tra tiền số
...
// nạp tiền cho cửa hàng
...
Nếu thanh tốn thành cơng ngân hàng sẽ trả lời cho cửa hàng dưới dạng ReceiptES, et, nt, v, s, RM, s', TimeB, signB, trong đĩ:
ReceiptES là thơng báo của ngân hàng,
(et, nt, v, s) là tiền điện tử cũ của khách hàng
RM là tiền cịn lại bằng số tiền của tiền điện tử xxx – cost giá hàng
s’ là chữ ký mới của ngân hàng, s' ≡
TimeB là nhãn thời gian
signB là chữ ký của ngân hàng
// tạo s’
string sRM = xxx – cost;
string sDataRemain = sPubKT+','+sSoV+','+sSoS+','+sRM;
string sSRM = SignData(sDataRemain,sPriKB);
// tạo văn bản trả lời và chữ ký
string sDataR = ReceiptES + ',' +sPubKT + ',' + sV + ',' + sS + ',' + sRM + ',' + sSRM + ',' + sTimeB;
string sSignR = SignData(sDataR,sPriKB);
string sReturn ="" + sDataR + "" + sSignR + "";
// trả lại văn bản trả lời cho cửa hàng
return sReturn;
}
Khi nhận đựơc trả lời từ ngân hàng cửa hàng sẽ kiểm tra chữ ký của ngân hàng, nếu chữ ký hợp lệ cửa hàng xem thơng báo của ngân hàng cĩ phải là thanh tốn được chấp nhận hay khơng. Nếu thanh tốn đựơc chấp nhận cửa hàng sẽ tạo văn bản cĩ dạng: License, ReceiptA, et, nt, v, s, RM, s', TimeES, signES và gửi cho khách hàng.
Trong đĩ:
License là chứng chỉ cho phép khách hàng nhận hàng
ReceiptA thơng báo của cửa hàng cho khách hàng
et, nt, v, s, RM, s' là tiền điện tử cịn lại
TimeES là nhãn thời gian
signES là chữ ký của cửa hàng
...
// gọi web service của ngân hàng
BankService.CheckECash service = new Shop.BankService.CheckECash();
string sResult = service.CheckDigiCash(sAccountB,sData,sSign);
// lấy thơng tin và chữ ký từ kết quả trả về của ngân hàng
string sDataB = ...
string sSignB = ...
// kiểm tra chữ ký của ngân hàng
if (CheckSign(sDataB,sSignB,sBankPubkey))
{
// tạo nội dung trả về và chữ ký
string sDataES = sLicenseA + ‘,’ + sReceiptA + ‘,’ + sPubKT + ‘,’ + sV + ‘,’ + sS + ‘,’ + RM + ‘,’ + sSRM + sTimeES;
string sSignES = objCrypto.SignData(sData,sPriKES);
string sReturn = "" + sDataES + " " +sSignES + "";
// tạo văn bản trả lời cho khách hàng
CreateFileText(filename,sReturn);
...
Văn bản trả lại cho khách hàng được lưu ở file cĩ phần mở rộng là *.rmo
Tạo tiền số cịn lại
Sau khi nhận được trả lời của cửa hàng dưới dạng file *.rmo khách hàng cĩ thể tạo tiền số cịn lại chính là (et, nt, v, s, RM, s').
Đầu tiên khách hàng sẽ kiểm tra chữ ký của cửa hàng, nếu chữ ký là hợp lệ khách hàng sẽ tạo tiền điện tử cịn lại. Chữ ký của cưẳ hàng được kiểm tra bằng khĩa cơng khai cho dưới dạng chứng chỉ khĩa cơng khai của cửa hàng.
...
// đọc thơng tin từ trả lời của cửa hàng
clsXML objXML = new clsXML(txtRM.Text);
string sData = objXML.GetXmlNodeContent("/Reply/Data");
string sSign = objXML.GetXmlNodeContent("/Reply/Sign");
// lấy thơng tin khĩa cơng khai của cửa hàng
string sPubKES = objCrypto.GetPublicKeyFromCert(txtPubKES.Text);
// kiểm tra chữ ký của cửa hàng
if (CheckSign(sData,sSign,sPubKES))
{
// lấy thơng tin tiền điện tử cịn lại
string sPubKT = ...
string sV = ...
string sS = ...
string sRM = ...
string sSRM = ...
// tạo tiền số cịn lại
string sText = "" + sPubKT + "" +
sV + "" + sS + "" + sRM + "" + sSRM +
"";
CreateFileText(saveFileDialog1.FileName,sText);
}
...
Giao diện form tạo tiền số cịn lại:
Các chức năng khác của hệ thống ngân hàng
Ngồi chức năng tạo tiền số và thực hiện thanh tốn, ngân hàng cịn cĩ các chức năng sau:
Quản lý khách hàng
Quản lý tài khoản
Quản lý tiền điện tử đã dùng.
Hệ quản trị cơ sở dữ liệu mà em dùng cho hệ thống này là hệ quản trị Microsoft SQL Server. Hệ quản trị này cĩ chức năng tạo các cơ sở dữ liệu, tạo bảng, tạo các câu truy vấn …
Cơ sở dữ liệu gồm cĩ bảng và các câu truy vấn phục vụ cho mục đích xử lý dữ liệu trong các bảng.
Bảng dùng biểu diễn một lớp đối tượng. Bảng gồm các dịng và các cột. Mỗi hàng là một đối tượng cụ thể.Mỗi cột là một thuộc tính của đối tượng.
Các câu truy vấn trong SQL Server
Truy vần tìm kiếm
SELECT select_list FROM table_source [ WHERE search_condition ] [ ORDER BY order_expression [ ASC | DESC ] ]
select_list
Các cột được chọn cho tập kết quả. Danh sách chọn là một dãy các biểu thức phân cách bằng dấu phẩy.
*
Chỉ ra rằng mọi cột trong mọi bảng và view trong phần FROM sẽ được trả lại. Các cột được trả lại theo bảng và theo thứ tự chúng tồn tại trong bảng.
table_name.*
Giới hạn phạm vi của * vào một bảng.
column_name
Nếu tên của cột trả lại. Bảo đảm tên column_name rõ ràng để ngăn ngừa tính trạng tham chiếu phức tạp, như hai bảng trong phần FROM cĩ các cột trùng tên. Ví dụ, bảng Customers và Orders trong cơ sở dữ liệu Northwind database cùng cĩ cột tên là ColumnID. Nếu hai bảng được dùng cho một truy vấn customer ID cĩ thể được định nghĩa trong danh sách lựa chọn là Customers.CustomerID.
expression
Nĩ là tên cột, hằng, hàm hay một kết hợp của các tên cột, các hằng, và các hàmg liên kết nhau bởi các tốn tử hay một câu truy vấn phụ.
column_alias
Là tên khác để thay thé tên cột trong tập kết quả truy vấn. Ví dụ một tên khác là "Quantity", hay "Quantity to Date", hay "Qty" cĩ thể dùng cho một cột tên là quantity.
table_source
Các bảng thực hiện tìm kiém dữ liệu
Đặc tả các điều kiện cho các dịng được chọn. Khơng cĩ giới hạn số thuộc tính cĩ thể cĩ trong một điều kiện.
order_by_expression
Đặc tả cột được sắp xếp. Cột được sắp xếp cĩ thể cho bằng tên cột, một biểu thức, hay một số nguyên khơng âm biểu diễn vị trí tên cột hoặc biểu thức trong select_list.
Truy vấn thêm dịng thêm một hay nhiều dịng vào một bảng.
INSERT [INTO] table_or_view [(column_list)] data_values
Câu lệnh đưa dữ liệu data_values vào một hay nhiểu dịng vào bảng hay view. column_list là danh sách tên cột, cách nhau dấu phẩy, dùng để xác định các cột mà dữ liệu thêm vào. Nếu column_list khơng cĩ, mọi cột trong bảng sẽ nhận dữ liệu..
Truy vấn tạo sửa dữ liệu trong bảng
UPDATE { table_name } SET { column_name = { expression | DEFAULT | NULL } )
[ WHERE ]
Tham số
table_name
Tên bảng để cập nhập dữ liệu
SET
Đặc tả danh sách các cột hoặc biến được cập nhập.
column_name
Tên cột phải cĩ trong bảng đặc tả trong câu UPDATE.
expression
Là một biến, một giá trị, biểu thức hoặc một câu lệnh SELECT phụ trả lại một giá trị. Giá trị trả lại bằng expression thay thế giá trị tồn tại trong column_name.
Đặc tả các điều kiện cho các dịng được thêm vào hay xĩa đi. Khơng cĩ giới hạn số thuộc tính cĩ thể cĩ trong một điều kiện.
Câu truy vấn xĩa dịng trong bảng
DELETE FROM ( table_name }
[ WHERE { ]
table_name
Tên bảng để xĩa dữ liệu
Đặc tả các điều kiện cho các dịng được thêm vào hay xĩa đi. Khơng cĩ giới hạn số thuộc tính cĩ thể cĩ trong một điều kiện.
Stored procedure (thủ tục được lưu trữ)
Một thủ tục được lưu trữ là một đối tượng thực hiện được được dịch trước mà chứa một hoặc nhiều câu truy vấn SQL. Các thủ tục được lưu trữ cĩ các tham số đầu vào và đầu ra và cĩ thể tạo mã trả lại số nguyên.
Thực hiện một thủ tục tương tự như việc thực hiện một truy vấn được chuẩn bị trước, ngoại trừ thủ tục tồn tại là đối tượng được dịch khơng đổi trong cơ sở dữ liệu. Một thủ tục được lưu trữ cĩ thể che dấu các câu lệnh SQL phức tạp với một ứng dụng. Tức là thay vì phải trực tiếp tạo các câu lệnh truy vấn phức tạp, ứng dụng chỉ cần gọi một thủ tục chứa các câu truy vấn đĩ, với các tham số đầu vào cần thiết.
Mơ hình của việc thưc hiện truy vấn trong SQL Server
SQL Server
Ứng dụng
Stored Procedures
SQL Querries (SQL Statements)
Gọi
Thực hiện
Cú pháp của một thủ tục
CREATE PROCEDURE procedure_name
@varaible_list
AS
SQLStatements
procedure_name là tên của thủ tục
@varaible_list là danh sách biến
SQLStatements là các câu truy vấn trong SQL.
Thao tác với hệ quản trị CSDL trong C#
C# cung cấp khơng gian tên System.Data.SqlClient để thực hiện việc kết nối với cơ sở dữ liệu. Trong khơng gian tên cĩ các lớp đáng chủ ý sau:
Lớp System.Data.SqlClient.SqlConnection biểu diễn một kết nối mở tới một cơ sở dữ liệu SQL.
Giao diện lớp cĩ các thuộc tính và phương thức đáng chú ý:
public virtual new string ConnectionString [ get, set ] xâu dùng để mở một cơ sở dữ liệu SQL
public SqlConnection ( ) hàm khơi tạo tạo một đối tưộng SqlConnection.
public SqlConnection ( string connectionString ) tạo một đối tượng SqlConnection với xâu kết nối ConnectionString cho trước.
public virtual new void Open ( ) mở một kết nối cơ sở dữ liệu với các thuộc tính đặc tả bởi ConnectionString.
public virtual new void Close ( ) đĩng một kêt nối tới cơ sở dữ liệu.
Lớp System.Data.SqlClient.SqlCommand biểu diễn một câu lệnh SQL hay một stored procedure để thực hiện trong một cơ sở dữ liệu SQL.
Giao diện lớp cĩ các thuộc tính và phương thức đáng chú ý:
public System.Data.SqlClient.SqlConnection Connection [ get, set ] đối tượng SqlConnection dùng cho bởi một thể hiện của lớp SqlCommand, các câu lệnh phải thực hiện trên một kết nối cơ sở dữ liệu SQL.
public System.Data.SqlClient.SqlParameterCollection Parameters [ get] tập hợp các tham số của SqlCommand.
public virtual new System.Data.CommandType CommandType [ get, set ] kiểu câu lệnh của SqlCommand.
public virtual new string CommandText [ get, set ] câu lệnh SQL hay stored procedure để thực hiện trong cơ sở dữ liệu.
public SqlCommand ( ) khởi tạo một đĩi tượng SqlCommand
public SqlCommand ( string cmdText ) khởi tạo một đĩi tượng SqlCommand với câu truy vấn cmdText
public SqlCommand (string cmdText , System.Data.SqlClient.SqlConnection connection ) khởi tạo một đĩi tượng SqlCommand với câu truy vấn cmdText trên một kết nối cơ sở dữ liệu SQL connection.
public System.Data.SqlClient.SqlDataReader ExecuteReader ( System.Data.CommandBehavior behavior ) giử một câu lệnh cho bởi CommandText tới kết nối cơ sở dữ liệu SQL trong Connection, và tạo một System.Data.SqlClient.SqlDataReader với một trong các hành vi thuộc System.Data.CommandBehaviorvalues.
public virtual new System.Int32 ExecuteNonQuery ( ) thực hiện một câu lệnh SQL trên một kết nối và trả lại số dịng tác động.
Lớp System.Data.CommandBehavior miêu tả kết quả của một truy vấn và tác động của nĩ lên cơ sở dữ liệu. Nĩ cĩ thể là một trong các giá trị sau
CloseConnection: khi một câu lệnh đã được thực hiện thì đĩng kết nối khi một đối tượng DataReader được đĩng
Default: mặc định
KeyInfo
SchemaOnly
SequentialAccess
SingleResult
SingleRow
Lớp System.Data.CommandType miêu tả cách một câu lệnh được dịch. Nĩ cĩ thể là một trong các giá trị
StoredProcedure
TableDirect
Text
Lớp System.Data.SqlClient.SqlParameter biểu diễn một tham số cho một câu lệnh SqlCommand.
Giao diện lớp cĩ các thuộc tính và phương thức đáng chú ý:
public virtual new string ParameterName tên tham số
public virtual new object Value giá trị tham số
public SqlParameter ( ) hàm khởi tạo
Lớp System.Data.SqlClient.SqlParameterCollection biểu diễn tập các tham số SqlParameter
Phương thức đáng chú ý:
public System.Data.SqlClient.SqlParameter Add ( System.String parameterName , System.Object value ) thêm một SqlParameter cho bởi tên tham số và giá trị, vào trong tập hợp tham số SqlParameterCollection.
Lớp System.Data.SqlClient.SqlDataReader cung cấp phương tiện để đọc các dịng trong cơ sở dữ liệu SQL.
Các thuộc tính và
public const virtual new object this [ string] đọc một dịng trong đối tượng
public virtual new System.Boolean Read ( ) đưa con trỏ tới dịng tiếp theo
public virtual new void Close ( ) kết thúc việc đọc
Để thao tác với một cơ sở dữ liệu trong SQL Server em tạo lớp clsObjData. Các thuộc tính của lớp là
// một kết nối với cơ sở dữ liệu
SqlConnection myConnection;
// xâu chứa thơng số kết nối
static string strConn="";
// cấu trúc một tham số gồm tên tham số và giá trị
private struct Params
{
public string name;
public string strvalue;
}
// tập tham số câu lệnh cập nhập
private Params[] Update_Param = new Params[100];
// tập tham số câu lệnh xĩa
private Params[] Delete_Param = new Params[10];
// tập tham số câu lệnh chọn
private Params[] Select_Param = new Params[100];
// số tham số của một thao tác cập nhập, xĩa, hay lựa chọn
private int update_count = -1, delete_count = -1, select_count = -1;
Để tạo một kết nối với cơ sở dữ cần biết các thơng số: vị trí nguồn cơ sở dữ liệu, tên cơ sở dữ liệu, tài khoản đăng nhập. Các tham số này cĩ thể chứa trong một xâu kết nối, sau đĩ ta tạo một đới tượng SqlConnection để thực hiện kết nối trong xâu kết nối, khi thực hiện xong thao tác với cơ sở dữ liệu cần đĩng kết nối lại.
Các hàm mở và đĩng kết nối
// mở kết nối
public void OpenConnection()
{
myConnection = new SqlConnection();
myConnection.ConnectionString=strConn;
myConnection.Open();
}
// đĩng kết nối
public void CloseConnection()
{
myConnection.Close();
}
Thực hiện các thao tác
Chính là việc gọi các stored procedure trong cơ sở dữ liệu.
Khởi tạo tham số truyền cho các stored procedure
// khởi tạo lại tham sĩ cho một thao tác
protected void ResetParam(int key)
{
switch (key)
{
// thao tác cập nhập
case 1:
update_count = -1;
break;
// thao tác xĩa
case 2:
delete_count = -1;
break;
// thao tác lựa chọn
case 3:
select_count = -1;
break;
default:
break;
}
}
// thêm một tham sĩ vào tập tham số của một thao tác
protected void AddParam(int key, string _name, string _strvalue)
{
switch (key)
{
// cập nhập
case 1:
update_count++;
Update_Param[update_count].name = _name;
Update_Param[update_count].strvalue = _strvalue;
break;
// xĩa
case 2:
delete_count++;
Delete_Param[delete_count].name = _name;
Delete_Param[delete_count].strvalue = _strvalue;
break;
// lựa chọn
case 3:
select_count++;
Select_Param[select_count].name = _name;
Select_Param[select_count].strvalue = _strvalue;
break;
default:
break;
}
}
Các thao tác
// thao tác cập nhập
protected void Update(string str_store)
{
// mở kết nối
OpenConnection();
// thực hiện stored procedure tên là str_store
myCommand = new SqlCommand(str_store, myConnection);
// kiểu câu lệnh stored procedure
myCommand.CommandType = CommandType.StoredProcedure;
// nhập các tham số
myCommand.Parameters.Clear();
for (int i = 0; i <= update_count; i++)
myCommand.Parameters.Add(Update_Param[i].name, Update_Param[i].strvalue);
// thực hiện truy vấn
myCommand.ExecuteNonQuery();
// đĩng kết nối
myCommand.Dispose();
CloseConnection();
}
// thao tác xĩa
protected void Delete(string str_store)
{
// mở kết nối
OpenConnection();
// thực hiện stored procedure tên là str_store
myCommand = new SqlCommand(str_store, myConnection);
// kiểu câu lệnh stored procedure
myCommand.CommandType = CommandType.StoredProcedure;
// nhập các tham số
myCommand.Parameters.Clear();
for (int i = 0; i <= delete_count; i++)
myCommand.Parameters.Add(Delete_Param[i].name, Delete_Param[i].strvalue);
// thực hiện truy vấn
myCommand.ExecuteNonQuery();
// đĩng kết nối
myCommand.Dispose();
CloseConnection();
}
// thao tác lựa chọn
protected SqlDataReader Select(string str_store)
{
// mở kết nối
OpenConnection();
// thực hiện stored procedure tên là str_store
myCommand = new SqlCommand(str_store, myConnection); myCommand.CommandType = CommandType.StoredProcedure;
// nhập các tham số
myCommand.Parameters.Clear();/
for (int i = 0; i <= select_count; i++)
myCommand.Parameters.Add(Select_Param[i].name, Select_Param[i].strvalue);
// thực hiện truy vấn
myReader= myCommand.ExecuteReader(CommandBehavior.CloseConnection);
myCommand.Dispose();
return myReader;
}
Các chức năng khác của hệ thống ngân hàng.
Quản lý khách hàng
Quản lý khách hàng bao gồm các thao tác thêm một khách hàng mới, sửa thơng tin khách hàng, tìm kiếm khách hàng, xĩa khách hàng. Lưu ý khách hàng chỉ được xĩa khi khơng cĩ tài khoản trong ngân hàng.
Đâu tiên ta tạo bảng khách hàng; tblKhachHang
STT
Tên trường
Kiểu dữ liệu
Độ lớn
Ý nghĩa
Ràng buộc
ID
int
4 byte
Mã khách hàng
not null, khĩa
CMND
nvarchar
20 word
Số CMND
not null
Hoten
nvarchar
200 word
Họ và tên khách
not null
Diachi
nvarchar
1000 word
Địa chỉ khách
Dienthoai
nvarchar
20 word
Điện thoại khách
Ngaysinh
datetime
8 byte
Ngày sinh của khách
not null
Email
nvarchar
200 word
Địa chỉ hịm thư
SoTK
int
4 byte
Số tài khoản cĩ trong ngân hàng
Các stored procedure thực hiện các thao tác::
Tìm tất cả khách hàng
Tìm khách hàng theo họ tên, ngày sinh và số CMND
Thêm hoặc sửa thơng tin khách hàng
Xĩa khách hàng cho bởi ID khách hàng
Giao diện form quản lý khách hàng
Quản lý tài khoản:
Để quản lý ta cần tạo bảng tài khoản như sau: tblAccount
STT
Tên trường
Kiểu dữ liệu
Độ lớn
Ý nghĩa
Ràng buộc
SoTK
nvarchar
20 word
Số tài khoản
not null, khĩa
Sotien
nvarchar
50 word
Số tiền trong tài khoản
not null
MSKH
int
4 byte
Mã số khách hàng
not null
NgayHetHan
datetime
8 byte
Ngày hết hạn
not null
MSTK
nvarchar
50 word
Mã số tài khoản
not null
Các store procedure thực hiện các thao tác:
Lấy thơng tin của tất cả tài khoản
Lấy thơng tin từ một tài khoản cho bởi SoTK
Tìm tài khoản từ SoTK và MSTK
Tìm tài khoản của khách hàng cĩ MSKH là @MSKH
Thêm một tài khoản của khách hàng MSKH và cập nhập số tài khoản của khách hàng tăng lên 1.
Rút tiền từ tài khoản cho bởi @SoTK, lượng tiền @Money
Nạp tiền vào tài khoản cho bởi @SoTK, lượng tiền @Money
Xĩa một tài khoản và trừ đi 1 trong số tài khoản của khách hàng cĩ tài khoản đĩ
Giao diện form quản lý tài khoản
Quản lý tiền số đã dùng
Trước tiên ta tạo bảng tiền số đã dùng: tblECash
STT
Tên trường
Kiểu dữ liệu
Độ lớn
Ý nghĩa
Ràng buộc
ID
int
4 byte
ID tiền số
not null, khĩa
PubKT
nvarchar
4000 word
Khĩa cơng khai tạm thời
not null
SoV
nvarchar
1000 word
Số v
not null
SoS
nvarchar
1000 word
Số s
not null
RM
int
4 byte
Tiền cịn lại
not null
ExpireDay
datetime
8 byte
Ngày hết hạn
not null
Các stored procedure thực hiên các thao tác sau:
Thêm mới hoặc cập nhập một đồng tiền điện tử
Lấy thơng tin của một đồng tiền xác định bởi số v, số s và khĩa cơng khai tạm thời.
Trừ đi số tiền cịn lại trong tiền điện tử xác định bằng ID tiền
Xĩa tiền đã hết hạn
Giao diện form quản trị tiền điện tử đã dùng
Các chức năng khác của hệ thống cửa hàng
Gồm cĩ:
Quản lý hàng hĩa
Hiển thị hàng hĩa, cĩ hai dạng
Hiển thị tại trang chủ
Hiển thị theo cây menu
Giỏ hàng (shopping cart)
Quản lý hàng hĩa
Tạo bảng hàng hĩa: tblSanpham
STT
Tên trường
Kiểu dữ liệu
Độ dài
Ý nghĩa
Ràng buộc
ID
int
4 byte
ID sản phẩm
not null, khĩa
IDMenu
int
4 byte
ID Menu
not null
Name
nvarchar
300 word
Tên sản phẩm
not null
Image
nvarchar
500 word
Tên file ảnh
TomTat
nvarchar
3000 word
Thơng tin tĩm tắt
ChiTiet
ntext
16 byte
Thơng tin chi tiết
Gia
int
4 byte
Giá sản phẩm
NgayGio
datetime
8 byte
Ngày giờ cập nhập
Active
smallint
2 byte
Hiển thị
ActiveInMain
smallint
2 byte
Hiển thị trang chủ
FileName
nvarchar
300 word
Tên file đính kèm
Các thủ tuc cần tao
Thêm hoặc cập nhập sản phẩm
Thủ tục xĩa sản phẩm cho bởi ID sản phẩm
Lấy thơng tin tất cả sản phẩm
Lấy thơng tin một sản phẩm bằng ID sản phẩm
Giao diện form quản trị sản phẩm
Hiển thị sản phẩm
Tại trang chủ sẽ hiển thị các sản phẩm do người quản trị lựa chọn. Nếu khách hàng chọn các menu khác nhau trên cây menu sẽ hiển ra các sản phẩm tương ứng trong menu đĩ.
Các thủ tục cần tao
Thủ tục chọn ra tất cả sản phẩm từ ID menu, ID ngơn ngữ
Thủ tục chọn sản phẩm hiện thị trang chủ theo ID ngơn ngữ
Giao diện sản phẩm hiển thị trang chủ
Giao diện sản phẩm trong menu “Sách phần cứng”
Giỏ hàng
Khi khách hàng bấm thêm sản phẩm vào giỏ hàng thì từ ID của sản phẩm được chọn ta lấy ra các thơng tin như tên sản phẩm, giá của sản phẩm và tạo thơng kê các hàng hĩa khách hàng đã chọn.
Giao diện giỏ hàng
Tài liệu tham khảo
Electronic commerce, nguồn www.Wikipedia.com
Electronic money, nguồn www.Wikipedia.com
Merchant account, nguồn www.Wikipedia.com
Payment gateway, nguồn www.Wikipedia.com
Transport Layer Security, nguồn www.Wikipedia.com
Blind signatures for untracable payments, tác giả D.Chaum, nguồn Advances in Cryptology CRYPTO '82
Untracable electronic cash, tác giả D.Chaum, Amos Fiat, và Moni Naor, nguồn Advances in Cryptology CRYPTO '88
Security without Identification: Transaction Systems to make Big Brother Obsolet, tác giả David Chaum
Online cash check, tác giả David Chaum
Card Compare, tác giả David Chaum
Digicash, tác giả Mandana Jahanian Farsi, Gưteborg University
How to Make E-cash with Non-repudiation and Anonymity, tác giả Song, R., and Korba, L, học viện cơng nghệ Canada
Các tài loại khác từ Internet
Các file đính kèm theo tài liệu này:
- DO71.DOC