CryptoAPI 로 데이터 암호 화

8260 단어
또는 CryptoAPI 라 고도 부 르 면 기본 적 인 알고리즘 을 고려 하지 않 고 응용 프로그램 에 강력 한 암호 화 기능 을 편리 하 게 추가 할 수 있 습 니 다.본 고 는 CryptoAPI 와 그 에 사용 되 는 데이터 암호 화 원 리 를 간단하게 소개 한 다음 에 CryptoAPI 로 암호 화 프로그램 을 작성 하 는 대체적인 절 차 를 제시 하고 마지막 으로 한 파일 의 암호 화, 복호화 프로그램 을 예 로 들 어 CryptoAPI 의 일부 기능 을 보 여 주 었 다.
1. CryptoAPI 소개
- CryptoAPI 는 수학 적 계산 을 완성 하기 위해 암호 서비스 제공 자 모듈 (CSP) 이 있어 야 하 는 함수 입 니 다.Microsoft 는 RSA Base Provider 를 묶 어 운영 체제 급 에 CSP 를 제공 하고 RSA 회사 의 공개 키 암호 화 알고리즘 을 사용 하 며 필요 에 따라 더 많은 CSP 를 응용 에 추가 할 수 있 습 니 다.실제로 CSP 는 특수 하드웨어 장치 (예 를 들 어 스마트 카드) 와 함께 데이터 암호 화 를 할 수 있다.CryptoAPI 인 터 페 이 스 는 간단 한 함수 호출 을 통 해 데 이 터 를 암호 화하 고 공개 키 를 교환 하 며 메 시 지 를 해시 하여 요약 을 만 들 고 디지털 서명 을 생 성 할 수 있 습 니 다.가능 한 CSP 에서 CSP 를 사용 하 는 등 고급 관리 작업 도 제공 합 니 다.그 밖 에 CryptoAPI 는 전자상거래 에 사용 되 는 SET, 클 라 이언 트 / 서버 메 시 지 를 암호 화 하 는 PCT, 각 플랫폼 간 에 기밀 데이터 와 키 를 오 가 며 전달 하 는 PFX, 코드 서명 등 많은 고급 보안 서비스 에 기반 을 마련 해 주 었 다.CryptoAPI 의 시스템 구 조 는 다음 과 같 습 니 다.
- 현재 CryptoAPI 를 지원 하 는 윈도 시스템 은 윈도 95 OSR 2, 윈도 NT SP3 및 후속 버 전, 윈도 98, 윈도 2000 등 이 있다.CryptoAPI 설정 정 보 는 다음 키 를 포함 하여 레 지 스 트 에 저 장 됩 니 다.
HKEY_LOCAL_MACHINE\SOFTWARE\
Microsoft / Cryptography /Defaults
HKEY_CURRENT_USER/ Software / Microsoft
/ Cryptography /Providers

데이터 암호 화 원리
- 데이터 암호 화 프로 세 스 는 다음 그림 과 같다.
- CryptoAPI 는 세 션 키 와 공공 / 개인 키 쌍 을 사용 합 니 다.세 션 키 는 같은 암호 화 와 복호화 키 를 사용 합 니 다. 이 알고리즘 은 빠 르 지만 키 의 안전 한 전달 을 보장 해 야 합 니 다.공공 / 개인 키 는 하나의 공공 키 와 하나의 개인 키 를 사용 합 니 다. 개인 키 는 전문가 만 사용 할 수 있 고 공공 키 는 광범 위 하 게 전 파 될 수 있 습 니 다.키 쌍 중 하 나 를 암호 화 에 사용 하면 다른 하 나 는 복호화 에 사 용 됩 니 다.공공 / 개인 키 쌍 알고리즘 은 느 립 니 다. 보통 세 션 키 를 암호 화 하 는 데 만 사 용 됩 니 다.
- CryptoAPI 는 스 트림 인 코딩 과 블록 인 코딩 두 가지 기본 인 코딩 방법 을 지원 합 니 다.스 트림 인 코딩 은 명시 적 텍스트 의 모든 비트 에 인 코딩 위 치 를 만 들 고 속도 가 빠 르 지만 안전성 이 낮 습 니 다.블록 인 코딩 은 하나의 완전한 블록 (보통 64 비트) 에서 작업 하 며, 인 코딩 할 데 이 터 를 채 우 는 방법 으로 반올림 하여 여러 개의 완전한 블록 을 구성 해 야 합 니 다.이런 알고리즘 은 속도 가 비교적 느 리 지만 더욱 안전 하 다.
예 를 들다
- 다음은 두 개의 파일 암호 화 와 복호화 의 C 프로그램 세 션 을 예 로 들 어 CryptoAPI 의 강력 한 기능 을 보 여 줍 니 다.이 두 프로그램 은 모두 Win 32 콘 솔 응용 프로그램 으로 오류 처 리 를 생략 하 였 으 며, 실제 실행 시 가입 하 십시오.
① 파일 암호 화
#include < windows.h >
#include < stdio.h >
#include < stdlib.h >
#include < wincrypt.h >

// RC2 RC4
#ifdef USE_BLOCK_CIPHER
#define ENCRYPT_ALGORITHMCALG_RC2
#define ENCRYPT_BLOCK_SIZE8
#else
#define ENCRYPT_ALGORITHMCALG_RC4
#define ENCRYPT_BLOCK_SIZE1
#endif

void CAPIDecryptFile(PCHAR szSource,
PCHAR szDestination, PCHAR szPassword);

void _cdecl main(int argc, char *argv[])
{
PCHAR szSource= NULL;
PCHAR szDestination = NULL;
PCHAR szPassword= NULL;

//
if(argc != 3 && argc != 4) {
printf("USAGE: decrypt < source file >
< dest file > [ < password > ]/n");
exit(1);
}

// .
szSource = argv[1];
szDestination = argv[2];
if(argc == 4) {
szPassword = argv[3];
}
CAPIDecryptFile(szSource, szDestination, szPassword);
}

/*szSource ,szDestination
,szPassword */
void CAPIEncryptFile(PCHAR szSource, PCHAR
szDestination, PCHAR szPassword)
{
FILE *hSource = NULL;
FILE *hDestination = NULL;
INT eof = 0;
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTKEY hXchgKey = 0;
HCRYPTHASH hHash = 0;
PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;
PBYTE pbBuffer = NULL;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;

hSource = fopen(szSource,"rb"));// .
hDestination = fopen(szDestination,"wb") ;
//.
// CSP
CryptAcquireContext(&hProv, NULL, NULL,
PROV_RSA_FULL, 0));
if(szPassword == NULL) {
// ,
// .
CryptGenKey(hProv, ENCRYPT_ALGORITHM,
CRYPT_EXPORTABLE, &hKey)
//
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey);
//
CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0,
NULL, &dwKeyBlobLen);
pbKeyBlob = malloc(dwKeyBlobLen)) == NULL) ;
//
CryptExportKey(hKey, hXchgKey, SIMPLEBLOB,
0, pbKeyBlob, &dwKeyBlobLen));
//
CryptDestroyKey(hXchgKey);
hXchgKey = 0;
//
fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
//
fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
} else {
// ,
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
//
CryptHashData(hHash, szPassword, strlen(szPassword), 0);
//
//
CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey);
//
CryptDestroyHash(hHash);
hHash = 0;
}

// , ENCRYPT_BLOCK_SIZE
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
// ,
if(ENCRYPT_BLOCK_SIZE > 1) {
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
} else {
dwBufferLen = dwBlockLen;
}
//
pbBuffer = malloc(dwBufferLen);
//
do {
// dwBlockLen
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
eof = feof(hSource);
//
CryptEncrypt(hKey, 0, eof, 0, pbBuffer,
&dwCount, dwBufferLen);
//
fwrite(pbBuffer, 1, dwCount, hDestination);
} while(!feof(hSource));
printf("OK/n");
……// 、
}



void CAPIDecryptFile(PCHAR szSource, PCHAR
szDestination, PCHAR szPassword)
{
……// 、

CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);
if(szPassword == NULL) {
// ,
//
fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);
pbKeyBlob = malloc(dwKeyBlobLen)) == NULL);
// .
fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
// CSP
CryptImportKey(hProv, pbKeyBlob,
dwKeyBlobLen, 0, 0, &hKey);
} else {
// ,
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
CryptHashData(hHash, szPassword, strlen(szPassword), 0);
CryptDeriveKey(hProv, ENCRYPT_ALGORITHM,
hHash, 0, &hKey);
CryptDestroyHash(hHash);
hHash = 0;
}

dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
if(ENCRYPT_BLOCK_SIZE > 1) {
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
} else {
dwBufferLen = dwBlockLen;
}
pbBuffer = malloc(dwBufferLen);

//
do {
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
eof = feof(hSource);
//
CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount);
//
fwrite(pbBuffer, 1, dwCount, hDestination);
} while(!feof(hSource));
printf("OK/n");
……// 、
}

- 상기 코드 는 Windows NT 4.0, Visual C + + 6.0 환경 에서 컴 파일 되 었 습 니 다.
- 암호 화 데 이 터 를 직접 사용 하 는 것 을 제외 하고 CryptoAPI 는 디지털 서명 을 생 성하 고 확인 하 는 데 광범 위 하 게 사용 되 는데 여기 서 일일이 예 를 들 어 설명 하지 않 고 관심 있 는 독 자 는 MSDN 문 서 를 참고 할 수 있다.
 
 
발췌:http://blog.chinaunix.net/u1/59687/showart_475160.html

좋은 웹페이지 즐겨찾기