NAME
encrypt, setkey, encrypt_r, setkey_r - 64비트 메시지 암호화하기
SYNOPSIS
#define _XOPEN_SOURCE /* feature_test_macros(7) 참고 */
#include <unistd.h>
void encrypt(char block[64], int edflag);
#define _XOPEN_SOURCE /* feature_test_macros(7) 참고 */
#include <stdlib.h>
void setkey(const char *key);
#define _GNU_SOURCE /* feature_test_macros(7) 참고 */
#include <crypt.h>
void setkey_r(const char *key, struct crypt_data *data);
void encrypt_r(char *block, int edflag, struct crypt_data *data);
모두 -lcrypt
로 링크 필요.
DESCRIPTION
이 함수들은 64비트 메시지를 암호화 및 복호화한다. setkey()
함수는 encrypt()
에서 쓰는 키를 설정한다. 그때 쓰이는 key
인자는 64바이트짜리 배열이며 각 바이트가 숫자 값 1 또는 0이다. n=8*i-1인 key[n]은 무시하며, 따라서 실제 키 길이는 56비트다.
encrypt()
함수는 전달받은 버퍼를 변경하는데, edflag
가 0이면 암호화, 1이면 복호화다. key
인자처럼 block
역시도 암호화하는 실제 값의 비트 벡터 표현이다. 같은 벡터로 결과가 반환된다.
이 두 함수는 재진입 가능하지 않다. 즉 키 데이터를 정적 저장 공간에 둔다. setkey_r()
및 encrypt_r()
함수는 재진입 가능 버전이다. 다음 구조체에 키 데이터를 담는다.
struct crypt_data {
char keysched[16 * 8];
char sb0[32768];
char sb1[32768];
char sb2[32768];
char sb3[32768];
char crypt_3_buf[14];
char current_salt[2];
long current_saltbits;
int direction;
int initialized;
};
setkey_r()
을 호출하기 전에 data->initialized
를 0으로 설정해야 한다.
RETURN VALUE
이 함수들은 아무 값도 반환하지 않는다.
ERRORS
위 함수들을 호출하기 전에 errno
를 0으로 설정해야 한다. 성공 시에는 errno
가 바뀌지 않는다.
ENOSYS
- 함수가 제공되지 않는다. (예를 들어 과거의 미국 수출 규제 때문에.)
VERSIONS
더이상 안전하지 않다고 보는 DES 블록 암호를 쓰기 때문에 glibc 2.28에서 crypt()
, crypt_r()
, setkey()
, setkey_r()
이 제거되었다. 응용에선 libgcrypt
같은 현대적인 암호 라이브러리로 전환해야 한다.
ATTRIBUTES
이 절에서 사용하는 용어들에 대한 설명은 attributes(7)를 보라.
인터페이스 | 속성 | 값 |
---|---|---|
encrypt() , setkey() |
스레드 안전성 | MT-Unsafe race:crypt |
encrypt_r() , setkey_r() |
스레드 안전성 | MT-Safe |
CONFORMING TO
encrypt()
, setkey()
: POSIX.1-2001, POSIX.1-2008, SUS, SVr4.
함수 encrypt_r()
과 setkey_r()
은 GNU 확장이다.
NOTES
glibc에서 사용 가능 여부
crypt(3) 참고.
glibc에서의 기능들
glibc 2.2에서 이 함수들은 DES 알고리즘을 사용한다.
EXAMPLES
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>
int
main(void)
{
char key[64];
char orig[9] = "eggplant";
char buf[64];
char txt[9];
for (int i = 0; i < 64; i++) {
key[i] = rand() & 1;
}
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
buf[i * 8 + j] = orig[i] >> j & 1;
}
setkey(key);
}
printf("Before encrypting: %s\n", orig);
encrypt(buf, 0);
for (int i = 0; i < 8; i++) {
for (int j = 0, txt[i] = '\0'; j < 8; j++) {
txt[i] |= buf[i * 8 + j] << j;
}
txt[8] = '\0';
}
printf("After encrypting: %s\n", txt);
encrypt(buf, 1);
for (int i = 0; i < 8; i++) {
for (int j = 0, txt[i] = '\0'; j < 8; j++) {
txt[i] |= buf[i * 8 + j] << j;
}
txt[8] = '\0';
}
printf("After decrypting: %s\n", txt);
exit(EXIT_SUCCESS);
}
SEE ALSO
cbc_crypt(3), crypt(3), ecb_crypt(3)
2021-03-22