CA를 통한 인증서 검증과 Server - Client 통신

CA를 활용한 클라이언트 인증서 검증을 하기 위해서 CA의 인증서와 CA 서명된 Client인증서, Server 인증서가 필요합니다. 아래의 포스팅을 참고하면 CA, Server, Client의 키 쌍들과 CA 인증서와 Server, Client 인증서를 생성할 수 있습니다. 

https://reakwon.tistory.com/239

 

openssl CA를 통한 Server - Client 인증서 검증 및 대칭키 공유 과정

CA 인증서로 상대방의 인증서 확인 방법 디렉토리 구조 디렉토리 구조는 아래와 같으며 각각 인증서를 생성하는 과정에서 여러 키와 인증서가 생성이 될 겁니다. # ls CA Client Server CA : Root CA로 CA

reakwon.tistory.com

이렇게 하면 디렉토리의 구조는 아래와 같게 됩니다. 

# ls
Client  RootCA  Server

 

Server/server.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
 
#include <openssl/rsa.h>    
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define CHK_NULL(x) if((x) == NULL) exit(1);
#define CHK_ERR(err, s) if((err) == -1) { perror(s); exit(1); }
#define CHK_SSL(err) if((err) == -1) { ERR_print_errors_fp(stderr); exit(2); }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx){

    char *str;
    X509 *cert = X509_STORE_CTX_get_current_cert(ctx);

    if (cert) {
        printf("Cert depth %d\n", X509_STORE_CTX_get_error_depth(ctx));
                
        str = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        CHK_NULL(str);
        printf("\t subject : %s\n", str);
        OPENSSL_free(str);

        str = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        CHK_NULL(str);
        printf("\t issuer : %s\n", str);
        OPENSSL_free(str);
    }

    return preverify_ok;
}
 
int main(void){

    int err, listen_fd, socket_fd;
    struct sockaddr_in server, client;
    size_t client_len;
   
    // SSL 관련 객체 
    SSL_CTX *ctx;
    SSL *ssl;
    X509 *client_cert;
    SSL_METHOD  *meth;
    
    char *str;
    char buf[128];
   
    printf("Server start!\n");

    // SSL 초기 셋팅 
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    meth = SSLv23_server_method();
    ctx = SSL_CTX_new(meth);  
   
    if(!ctx) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 서버의 인증서 설정 
    if(SSL_CTX_use_certificate_file(ctx, "./Server.crt", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 서버의 개인키 설정 
    if(SSL_CTX_use_PrivateKey_file(ctx, "./privkey-Server.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }

    // 개인키 사용 가능성 체크
    if(!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, "private key is not matched to public key.\n");
        exit(-1);
    }
    // 사용할 CA의 인증서 설정
    if(!SSL_CTX_load_verify_locations(ctx, "../RootCA/CA.crt", NULL)) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }

    // Client의 인증서를 검증하기 위한 설정, CA는 하나만 있다고 가정-> depth = 1
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_callback);
    SSL_CTX_set_verify_depth(ctx, 1); 
   
    // TCP socket 생성 이후 bind, listen, accept
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    CHK_ERR(listen_fd, "socket");
   
    memset(&server, 0x00, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(12340); 
 
    err = bind(listen_fd, (struct sockaddr*)&server, sizeof(server));
    CHK_ERR(err, "bind");
   
    err = listen(listen_fd, 5);
    CHK_ERR(err, "listen");
    
    client_len = sizeof(client);
    socket_fd = accept(listen_fd, (struct sockaddr*)&client, &client_len);
    CHK_ERR(socket_fd, "accept");
    close(listen_fd);
    
    // SSL 세션 생성 
    ssl = SSL_new(ctx);
    CHK_NULL(ssl);

    // SSL 접속 대기 , SSL_accept 완료 = SSL handshake 완료
    SSL_set_fd(ssl, socket_fd);
    err = SSL_accept(ssl);    
    CHK_SSL(err);
   
    // 사용하는 Cipher 
    printf("SSL is using cipher %s\n", SSL_get_cipher(ssl));
   
    // 클라이언트의 인증서를 받고 검증
    client_cert = SSL_get_peer_certificate(ssl);
    CHK_NULL(client_cert);


    if(SSL_get_verify_result(ssl) == X509_V_OK){
        printf("verify cert OK\n");
        X509_free(client_cert);
    } else {
        printf("verify cert Failed\n");
    }

   
    // 클라이언트로부터 메시지 수신
    err = SSL_read(ssl, buf, sizeof(buf)-1);
    CHK_SSL(err);
    buf[err] = 0;
    printf("From Client '%s'\n", buf);
   
    err = SSL_write(ssl, "Hello, Client!", strlen("Hello, Client!"));
    CHK_SSL(err);
   
    //자원 해제 
    close(socket_fd);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
   
    return(0);
}

  • SSL Context : Context는 cipher, TLS 버전, 인증서 및 암호 파라미터들의 모음입니다. 이를 기반으로 SSL session이 생성됩니다.  그러니까 인증서나 키 등의 세션들이 공통적으로 사용하는 데이터를 미리 설정해둠에 따라 세션이 만들어질때마다 이런 데이터를 미리 준비하는 과정이 없어집니다. 그 말은 즉, 시간이 줄어든다는 뜻입니다.
  • SSL Session : Session은 Server와 Client간의 연결이 실제 이루어진 것을 의미합니다. 이 세션에서 데이터의 전송이 이루어집니다. Server나 Client간의 세션이 없다면 만들어지고, 만들어져있다면 세션을 다시 재활용하는 것도 가능합니다. 

인증서 검증 

Client의 인증서를 검증하기 위해서는 SSL_CTX_set_verify, 그리고 SSL_CTX_set_verify_depth를 지정해야합니다. SSL_CTX_set_verify에 SSL_VERIFY_PEER 옵션 지정 후 verify_callback 함수를 통해서 커스텀한 검증을 할 수 있는데, verify_callback함수에 preverify_ok라는 인자는 이전에 검증 과정의 결과를 알려줍니다. depth에 따라서 여러번 호출이 됩니다.

위 verify_callback 함수는 SSL_CTX_set_verify_depth에 의해서 depth를 지정해 줄 수 있는데, depth에 따라 인증서를 어느 수준까지 인증할 것이냐를 정의해줄 수 있습니다. 예를 들어 depth가 1이면 Client(depth 0)와 그 인증서를 발행한 CA(depth 1)의 인증서를 검증하게 되는 것이구요. depth가 2일 경우에는 위 단계에서 CA의 인증서를 발생한 상위의 CA(depth 2)의 인증서를 검증합니다.

이후 잘 검증되었는지를 확인하는 SSL_get_verify_result 함수를 이용해 문제없이 인증서가 검증되었는지 확인할 수 있습니다.

 

Client/client.c

#include <stdio.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
 
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define CHK_NULL(x) if((x) == NULL) exit(1);
#define CHK_ERR(err, s) if((err) == -1) { perror(s); exit(1); }
#define CHK_SSL(err) if((err) == -1) { ERR_print_errors_fp(stderr); exit(2); }
 
int main(void)
{
    int err, socket_fd;
    struct sockaddr_in server;
   
    SSL_CTX *ctx;
    SSL *ssl;
    X509 *server_cert;
    char *str;
    char buf[128];
    SSL_METHOD    *method;
   
    //초기 세팅
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    method = SSLv23_client_method();
    ctx = SSL_CTX_new(method);
    CHK_NULL(ctx);
   
    // Context에서 사용할 인증서 설정
    if(SSL_CTX_use_certificate_file(ctx, "./Client.crt", SSL_FILETYPE_PEM) <= 0) {    
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // Context에서 사용할 개인키 설정
    if(SSL_CTX_use_PrivateKey_file(ctx, "./privkey-Client.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(-1);
    }
   
    // 개인키 사용가능성 확인
    if(!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, "Private key is not matched to public key\n");
        exit(-1);
    }
   
    // Socket의 Connect까지 설정하는 과정
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    CHK_ERR(socket_fd, "socket error ");
   
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_port = htons(12340); 
   
    err = connect(socket_fd, (struct sockaddr*)&server, sizeof(server));
    CHK_ERR(err, "connect error ");
   
    //SSL 세션 객체 생성
    ssl = SSL_new(ctx); 
    CHK_NULL(ssl);
   
    //SSL객체에 socket fd를 설정
    SSL_set_fd(ssl, socket_fd);
    err = SSL_connect(ssl); 
    CHK_NULL(err);
   
    printf("SSL is using cipher %s\n", SSL_get_cipher(ssl));
   
    // 서버의 인증서를 가져옴
    server_cert = SSL_get_peer_certificate(ssl);
    CHK_NULL(server_cert);

    printf("Server certificate:\n");
   
    //인증서의 몇가지 정보를 출력
    str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0);
    CHK_NULL(str);
    printf("\t subject: %s\n", str);
    OPENSSL_free(str);
   
    /* 인증서의 issuer를 출력한다. */
    str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0);
    CHK_NULL(str);
    printf("\t issuer: %s\n", str);
    OPENSSL_free(str);
   
    X509_free(server_cert);
   
    // 서버에게 메시지를 전송
    err = SSL_write(ssl, "Hello World!", strlen("Hello World!"));
    CHK_SSL(err);
   
    // 서버로부터 메시지 수신
    err = SSL_read(ssl, buf, sizeof(buf)-1);
    CHK_SSL(err);
    
    buf[err] = 0;
    printf("From Server : '%s'\n", buf);

   
    // 세션 종료 및 ssl, ctx 자원 해제
    SSL_shutdown(ssl);   
    close(socket_fd);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
   
    return 0;
}

 

결과화면

인증서를 대충만들었기 때문에 구분이 잘 안가실텐데, 아래의 depth 1은 CA 인증서, depth 0은 Client 인증서의 정보를 나타냅니다. CA의 인증서를 보면 subject와 issuer가 같은 것을 알 수 있죠. 자기 자신의 인증서를 자신이 사이닝했습니다.

Server
# ./server
Server start!
Cert depth 1
    subject : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no
    issuer : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no
Cert depth 0
    subject : /C=KR/ST=Some-State/O=Internet Widgits Pty Ltd/CN=Client/emailAddress=client@dd.com
    issuer : /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no
SSL is using cipher TLS_AES_256_GCM_SHA384
verify cert OK
From Client 'Hello World!'
Client
# ./client
SSL is using TLS_AES_256_GCM_SHA384
Server certificate:
    subject: /C=KR/ST=Some-State/O=Internet Widgits Pty Ltd/CN=Server/emailAddress=server@dd.com
    issuer: /C=KR/ST=Some-State/O=CA/OU=CA/CN=CA/emailAddress=no
From Server : 'Hello, Client!'

 

참고한 자료

SSL Server - Client 코드 : http://pchero21.com/?p=603

CA, Server, Client 인증서 생성 : https://www.cs.toronto.edu/~arnold/427/19s/427_19S/tool/ssl/notes.pdf

인증서 검증 : https://tribal1012.tistory.com/m/213

 

반응형
블로그 이미지

REAKWON

와나진짜

,

CA 인증서로 상대방의 인증서 확인 방법

 

디렉토리 구조 

디렉토리 구조는 아래와 같으며 각각 인증서를 생성하는 과정에서 여러 키와 인증서가 생성이 될 겁니다.

# ls
CA  Client  Server

CA : Root CA로 CA의 개인키, 공개키, 인증서가 저장됩니다.

Client : Client의 개인키, 공개키, CSR, 인증서가 저장됩니다.

Server : Server의 개인키, 공개키, CSR, 인증서가 저장됩니다.

 

 

CA의 인증서 생성 절차

Root CA라고 가정하고 자신의 인증서를 생성하는 절차입니다.

1. private key 생성

# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:5 -out privkey-CA.pem

암호 알고리즘은 RSA를 사용하며 2048비트의 rsa 키 길이를 사용하는 개인키를 생성합니다. 추가로 rsa_keygen_pubexp로 exponent를 지정할 수 있습니다.

 

2. public key 생성

# openssl pkey -in privkey-CA.pem -pubout -out pubkey-CA.pem

생성된 private key의 쌍인 public key를 생성합니다.  

 

3.  Self-Sign한 인증서 생성

# openssl req -x509 -new -nodes -key privkey-CA.pem -sha256 -days 365 -out CA.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:State
Locality Name (eg, city) []:city
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CA  
Organizational Unit Name (eg, section) []:CA
Common Name (e.g. server FQDN or YOUR name) []:CA
Email Address []:no

 

Server 인증서 생성 

서버의 인증서를 CA의 개인키로 서명하는 절차입니다. 개인키, 공개키를 생성하는 절차는 CA와 같습니다. 

1. private key 생성

# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privkey-Server.pem

 

2. public key 생성

# openssl pkey -in privkey-Server.pem -pubout -out pubkey-Server.pem

 

3. CSR 생성

# openssl req -new -key privkey-Server.pem -out Server-req.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Server
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:no

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

 

4. CA 서명된 인증서 Server 생성

# openssl x509 -req -in Server-req.csr -CA ../CA/CA.crt -CAkey ../CA/privkey-CA.pem -CAcreateserial -out Server.crt -days 500 -sha256
Certificate request self-signature ok
subject=C = KR, ST = Some-State, L = Seoul, O = Server, emailAddress = no

 

Client 인증서 생성

Client의 개인키, 공개키를 생성하고 CA의 개인키로 서명합니다.

1. private key 생성

# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privkey-Client.pem

 

2. public key 생성

# openssl pkey -in privkey-Client.pem -pubout -out pubkey-Client.pem

 

3. CSR 생성

# openssl req -new -key privkey-Client.pem -out Client-req.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Client
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:no

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

 

4.  CA 서명된 Client 인증서 생성

# openssl x509 -req -in Client-req.csr -CA ../CA/CA.crt -CAkey ../CA/privkey-CA.pem -CAcreateserial -out Client.crt -days 500 -sha256
Certificate request self-signature ok
subject=C = KR, ST = Some-State, L = Seoul, O = Client, emailAddress = no

 

인증서 검증

  • 클라이언트에서 서버 인증서 검증
# cd Client
# openssl verify -CAfile ../CA/CA.crt ../Server/Server.crt
../Server/Server.crt: OK

 

  • 서버에서 클라이언트 인증서 검증
# cd Server
# openssl verify -CAfile ../CA/CA.crt ../Client/Client.crt 
../Client/Client.crt: OK

 

공개키 추출

  • 서버 인증서에서 서버 공개키 추출
# cd Client
# cp ../Server/Server.crt .
# openssl x509 -pubkey -in Server.crt -noout > pubkey-Server.pem

 

  • 클라이언트 인증서에서 클라이언트 공개키 추출
# cd Server
# cp ../Client/Client.crt .
# openssl x509 -pubkey -in Client.crt -noout > pubkey-Client.pem

 

 

대칭키  공유

  • 클라이언트에서 랜덤한 대칭키 생성 후 Server의 공개키로 암호화 
# cd Client
# openssl rand -out symkey.pem -base64 32
# hexdump -C symkey.pem 
00000000  51 4f 31 67 6d 5a 63 5a  6e 36 76 47 48 31 36 37  |QO1gmZcZn6vGH167|
00000010  39 47 47 72 68 58 35 43  69 69 6f 4b 33 64 34 41  |9GGrhX5CiioK3d4A|
00000020  2b 6f 38 67 4a 4c 49 4a  64 65 38 3d 0a           |+o8gJLIJde8=.|
0000002d
# openssl pkeyutl -encrypt -in symkey.pem -pubin -inkey pubkey-Server.pem -out symkey.enc

 

  • 클라이언트의 개인키로 서명
# openssl dgst -sha1 -sign privkey-Client.pem -out signature.bin symkey.pem

 

  • 서버에서 암호화된 대칭키 복호화 후 검증

# cp ../Client/signature.bin .
# cp ../Server/symkey.enc .
# hexdump -C symkey.pem 
00000000  51 4f 31 67 6d 5a 63 5a  6e 36 76 47 48 31 36 37  |QO1gmZcZn6vGH167|
00000010  39 47 47 72 68 58 35 43  69 69 6f 4b 33 64 34 41  |9GGrhX5CiioK3d4A|
00000020  2b 6f 38 67 4a 4c 49 4a  64 65 38 3d 0a           |+o8gJLIJde8=.|
0000002d
# openssl dgst -sha1 -verify pubkey-Client.pem -signature signature.bin symkey.pem
Verified OK

 

이제 이 대칭키를 가지고 암복호화 통신을 하면 됩니다.

 

반응형
블로그 이미지

REAKWON

와나진짜

,

dd 명령어 

dd 명령어는 파일을 복사하거나 sdcard 같은 저장장치에 데이터를 쓸 수 있게 해주거나, 혹은 반대로 저장장치나 파일로부터 데이터를 복사해올 수 있게 만들어주는 유용한 명령어입니다. 그래서 블록(Block)이라는 단위를 통해서 파일의 내용을 다른 파일이나 저장 장치로 쓸 수 있습니다. 이제부터 저장장치도 파일이라고 간주하고 설명하도록 하겠습니다.

사용법 1  :  파일 전체를 복사

기본적으로 dd 명령어는 아래와 같은 input file과 output file을 가지게 됩니다. 옵션이 아무것도 없죠. 이런 경우에는 파일의 전체를 복사합니다. 아래의 명령어는 /home/image.ext4 파일을 /dev/mmcblk0p2 파일로 복사합니다. 

# dd if=/home/image.ext4 of=/dev/mmcblk0p2
  • if : input file의 약자로 복사할 파일을 지정합니다.
  • of : output file의 약자로 출력이 될 파일을 지정합니다.

 

사용법2 : input의 내용을 output의 일부분으로 복사

위 명령어는 기존 output의 내용이 있던 없던 간에 무조건 input의 내용으로만 복사가 되었습니다. 하지만 output의 내용의 일부분만 input의 내용으로 복사할 경우나 추가할 경우에는 conv 옵션에 notrunc 값을 지정해야합니다. 참고로 여기서 conv는 convert의 줄임말입니다. 

# dd if=size512.bin of=size1024.bin conv=notrunc
  • conv=notrunc : output 파일의 내용을 자르지 않는다는 의미입니다.

 

사용법3 :  블록 사이즈 지정하고 원하는 바이트만큼 복사

블록사이즈는 사용자가 지정하기 나름인데 기본적으로 설정되어있는 블록 사이즈는 512바이트입니다. 블록 사이즈나 블록의 갯수를 지정하여 원하는 양의 크기대로 복사할 수 있습니다. bs 옵션은 block size의 의미로 블록의 크기를 지정하는데 사용됩니다. 만약 512바이트가 아닌 블록 사이즈가 1024바이트이길 원한다면 bs의 옵션에 1024를 지정해주면 됩니다. 그리고 그 블록을 몇개 복사할 것이냐를 지정할때는 count옵션을 사용하면 됩니다. 

아래와 같은 경우는 block size가 1이며 512의 블록을 output.bin으로 복사합니다. 이럴 경우에는 단순히 512바이트 만큼 복사가 되겠네요.

# dd if=/dev/vda1 of=output.bin bs=1 count=512
  • bs : block size의 의미로 블록의 크기
  • count : input file의 블록을 몇개 복사할 것인지를 지정

 

사용법4 : input 파일의 내용을 일부 건너 뛰고 복사 

input 파일에서 처음부터가 아닌 몇 블록을 건너 뛴 다음에 복사하고 싶을때는 skip 옵션을 사용하시면 됩니다. 

# dd if=size1024.bin  of=size512.bin bs=128 skip=1 count=1
  • skip : input 파일에서 건너 뛸 블록의 갯수를 의미합니다. 

위의 예에서는 블록 사이즈를 128바이트로 지정한뒤 한 블록을 건너 뛰어서 1개의 블록을 복사하는 예입니다.

 

블록의 갯수가 아니고 skip을 단순히 바이트 단위로 건너 뛰고 싶을 경우 iflag에 skip_bytes를 지정하면 됩니다.

# dd if=size1024.bin of=size512.bin skip=128 iflag=skip_bytes bs=128 count=1
  • iflag=skip_bytes : skip을 블록 단위가 아닌 바이트 단위로 인식하여 input의 내용을 건너 뜁니다. 

그래서 위의 두 예제는 같은 결과를 보여줍니다. 

 

사용법5 : output 파일의 내용을 일부 건너 뛰어 복사

skip옵션과 마찬가지로 output 파일의 블록을 건너 뛸 수도 있습니다. seek 옵션을 사용하면 됩니다. 

# dd if=size1024.bin of=size512.bin bs=128 seek=1 count=1
  • seek : 건너 뛸 output 파일의 블록 갯수를 지정합니다.

위의 예에서는 블록의 크기가 128바이트이며, size1024.bin의 블록 하나를 복사합니다. 이때 seek=1을 사용해 size512.bin의 블록 하나를 건너 뛴 자리에 복사가 됩니다.

 

역시 seek을 블록 단위가 아닌 바이트 단위로 인식시키려면 oflag에 seek_bytes를 지정하면 됩니다. 

# dd if=size1024.bin of=size512.bin bs=128 seek=128 count=1 oflag=seek_bytes
  • oflag=seek_bytes : seek을 블록 단위가 아닌 바이트 단위로 변경합니다. 

위 두 예제는 같은 결과를 보여줍니다.

 

사용법6 : 출력 파일이 존재할 때만 실행

출력 파일이 있어야만 실행해야할 경우에는 아래와 같은 명령어를 사용하면 됩니다. 

# dd if=size1024.bin of=size512.bin conv=nocreat
dd: failed to open 'size512.bin': No such file or directory
  • conv=nocreat : output 파일이 있을 경우에만 dd 명령어를 수행합니다. 

만약 파일이 존재하지 않는다면 위의 결과와 같이 output 파일이 존재하지 않는다는 오류를 발생시키고 명령어를 수행하지 않습니다.

 

dd명령은 이정도만 사용하면 무난하게 리눅스에서 사용하실 수 있을 겁니다. 

반응형
블로그 이미지

REAKWON

와나진짜

,