Hex로 된 데이터를 HexString으로, HexString을 Hex로 변환하는 경우가 종종 있었다. 

그럴때 마다 Hex convert to Hexstring ~~ 등등 구글링을 했었는데....

이번에 만든 걸로 쓸 곳에 쓰고 정리를 해보았다.

 

Hex 를 HexString으로 변환은 말그대로 Hex형태로 된 데이터를 HexString으로 변환하는 것이다.

쉽게 말하면 아래와 같다. 

 

Hex로 된 데이터가 있다. 

uint8_t hex[16]={0xA1,0xA2,0xA3,0xA4,0xB5,0xB6,0xB7,0xB8,0xC9,0xC0,0xCA,0xCB,0xDC,0xDD,0xDE,0xDF};

 

현재는 한 바이트당 hex로 표시된 것을 말 그대로 스트링형태로 바꾸는 것이다. 

예를 들어 0xA1의 경우 1바이트 Hex로 표시되어 있다.

이 때, A와 1을 문자형태로 만들어 0xA1이란 1바이트 Hex를 A1이란 2바이트의 문자열(0x41,0x31)로 만드는 것이다. 

 

반대로 HexString 은 A1이란 스트링을 보이는 그대로 0xA1이란 Hex로 만드는 것이다. 

 

설명이 애매한가....? 난 이해가 되니깐.. ㅎ 

 

먼저 Hex를 HexString으로 바꾸는 건 아래와 같다. 

int hex_convert_hexstring(uint8_t* data, uint8_t len, uint8_t* result){
	int i=0;
	int idx=0;
	for(i=0;i<len;i++){
		result[idx++]=(*(data+i))>>4 & 0x0f;
		result[idx++]=(*(data+i))& 0x0f;
	}

	for(i=0;i<idx;i++){
		if(result[i]>=10){
			result[i]=result[i]-10+'A';
		}else{
			result[i]=result[i]+'0';
		}
	}
    return idx;
}

data에는 변환할 Hex 데이터, len에는 data의 길이, result는 결과를 저장할 배열을 넣는다. 

변환된 후, result의 데이터 길이가 retrun된다. 

간단히 설명하자면..... 

Hex 값을 4비트씩 나누어서  result에 넣고, 문자열로 표현하기에 result에 넣은 값을 문자열 형태로 변환해주면 된다.

이 때, 10이 hex로 표현되면 A로 표현되므로 문자열로 변환하기 위해서 10이상의 값은 10을 빼주고 문자 'A'만큼 더해준다. 

이렇게 되면 10일 경우는 문자 'A', 11인경우 11-10+'A' 가 되므로 'A'+1 인 'B'가 된다. 

10보다 작을 때는 문자 '0'을 더해주어 0~9를 문자 형태로 변환한다. 

아스키 코드 표를 보면서 하면 더 쉽게 이해가 될 것이다. 

 

 

다음으로는 HexString에서 Hex로 변환하는 법이다. 

int hexstring_convert_hex(uint8_t* data,uint8_t len,uint8_t* result){
	int idx=0;
	int i=0;
	for (i=0;i<len;i++){
		if(*(data+i)>='A'){
			*(data+i)=*(data+i)-'A'+10;
		}else{
			*(data+i)=*(data+i)-'0';
		}
	}
	i=0;
	for(idx=0;idx<len/2;idx++){
		result[idx]=*(data+i++)<<4  | *(data+i++) & 0x0f;
	}
    return idx;
}

data에 hexstring을 넣고, len에 hexstirng의 길이를 넣고, result에 hex결과를 저장할 배열을 넣는다. 

변환된 후, hex데이터의 길이가 return 된다.

아까와는 반대로 hexString의 문자를 hex로 만들고, 2바이트씩 합쳐준다. 

 

실행 예시는 다음과 같다. 

int main(){
    int i=0;
    int string_len=0;
    int hex_len=0;
    uint8_t hex[16]={0xA1,0xA2,0xA3,0xA4,0xB5,0xB6,0xB7,0xB8,0xC9,0xC0,0xCA,0xCB,0xDC,0xDD,0xDE,0xDF};
    uint8_t hex_string[64];
    uint8_t hex_result[64];

    string_len=hex_convert_hexstring(hex,sizeof(hex),hex_string);

    for(i=0;i<string_len;i++){
        printf("%C ",hex_string[i]);
    }
    printf("\r\n");
    printf("%s\r\n",hex_string); //A1A2A3A4B5B6B7B8C9C0CACBDCDDDEDF

    hex_len=hexstring_convert_hex(hex_string,string_len,hex_result);
    
    for(i=0;i<hex_len;i++){
        printf("%02X ",hex_result[i]); //A1 A2 A3 A4 B5 B6 B7 B8 C9 C0 CA CB DC DD DE DF
    }
    printf("\r\n");
    return 0;

}

주석처리가 실제 프린트된 내용인데 잘 변환된 것 같다.

 

끝 !

반응형

'지식저장소 > C' 카테고리의 다른 글

[C] Ring Buffer / 링버퍼 구현  (0) 2022.03.29
[C/BOJ] 9012 괄호 - Stack이용  (0) 2022.02.16
[C]구조체를 이용한 Stack 구현  (0) 2022.02.16
[C/STM32] Uart로 printf 대신하기  (0) 2022.01.14
[C] ARIA 128 암호화  (2) 2021.09.03

리눅스를 쓰기 시작하면서 윈도우와는 달리 키보드를 더 많이 쓰게 되었다....

정말 기초 중의 기초이면서 가장 먼저하고 거의 매일하는 일은 터미널 창 띄우기가 아닐까..?

터미널 창을 이용하여 이것저것하면서 내가 실제 터미널 관련해서 쓰는 단축키들은 아래와 같다. 

 

먼저 터미널 창을 띄워야 한다. 

터미널 창 띄우기 : CTRL + ALT + T

 

터미널 창을 띄우는 것으로 터미널 관련 사용법의 반을 익혔다.

 

작업을 하다보면 터미널 창이 많아지는 경우가 있는데 터미널 창을 많이 열다 보면 찾기도 힘들고 보기도 힘들다

그래서 1개의 터미널 창에 인터넷 브라우저와 같이 Tab을 만든다. 

터미널 탭 만들기 : CTRL + SHIFT + T

 

탭 창을 만들었으니 터미널 창 자체를 여러개 만들지 않고 1로 깔끔하게 쓸 수 있게 되었다.

여러개의 탭을 만들었으면 앞에서 부터 1,2,3 번호가 있다고 생각하고 아래의 단축키를 누르면 해당 탭으로 이동할 수있다. 

터미널 탭 바꾸기 : ALT + 해당 탭 창 번호

 

작업이 끝나서 탭을 닫아야할 경우 해당 탭으로 이동해서 터미널 탭 종료를 한다.

터미널 탭 종료 : CTRL + SHIFT + W

 

작업하는 터미널 창 크기가 작아서 내용이 짤리는가? 문제없다.

터미널 창 최대화 : ALT + F10

 

창을 다시 줄이려면 ALT + F10을 한번 더 눌러주자.

 

터미널 창 자체를 닫는 건 국룰인 ALT + F4 또는 CTRL + SHIFT + Q

 

터미널 창 안의 내용을 복사하려면 복사할 부분을 드래그 등으로 선택한 후, 

터미널 창 내에서 복사 : CTRL + SHIFT + C

 

터미널 창 내에 붙여넣기를 하고 싶다면?

터미널 창 내에 붙여넣기 : CTRL +SHIFT + V

 

로그 파일을 따로 만들지 못해 터미널 출력에서 특정 단어를 찾아야한다면 ? 

터미널 창 내에서 찾기 : CTRL + SHIFT + F

 

터미널 창을 열고 닫고, 탭을 만들고 이동하고 닫고,  창을 키우고 줄일 수 있고,

복사하고, 붙여넣고, 특정 문자를 찾을 수 있는 정도면 불편함없이 사용하는 것 같다. 

 

기초이지만 자주쓰는 터미널 창 명령어

끝 !

 

반응형

'지식저장소 > 이것저것' 카테고리의 다른 글

[Linux ] minicom 로그 저장/캡쳐하기  (0) 2022.06.22

이번엔 Golang에서 제공되는 라이브러리를 이용하여 AES CFB 암호화를 하고 Base64로 인코딩 하였다.

암호화 이론은.... 설명할 수준까지는 안되기에 다른 자료나 블로그들을 참조하였다

CFB로 암호화하고 Binary 데이터를 String 형태로 변경하는 Base64까지 적용하였다.

실행할 때 Key값을 인자로 넣고 실행을 한다.

그 후, 암호화할 내용들을 입력하면 끝 !

Base64를 적용하지 않으려면 EncryptAESCFB까지만 진행하면 된다.

윈도우용으로 사용하려면 크로스 컴파일 하면 무난히 사용 가능할 듯 하다.

- 소스코드

// main.go
package main

import (
	"bufio"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"encoding/base64"
	"fmt"
	"os"
)

var iv = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}

func main() {
	keyValue := os.Args[1]
	key := make([]byte, 16)
	md5Key := md5.Sum([]byte(keyValue))

	for i, v := range md5Key {
		key[i] = v
	}

	scanner := bufio.NewScanner(os.Stdin)

	for scanner.Scan() {
		ucl := scanner.Text()
		fmt.Println("----------------------------------")
		fmt.Println("Plain Data : ")
		fmt.Printf("[")
		for i, val := range ucl {
			if i == len(ucl)-1 {
				fmt.Printf("0x%02X", val)
			} else {

				fmt.Printf("0x%02X, ", val)
			}
		}
		fmt.Printf("]\n")
		fmt.Println(ucl)

		encrypted := make([]byte, len(ucl))
		err := EncryptAESCFB(encrypted, []byte(ucl), key, iv)
		if err != nil {
			panic(err)
		}
		fmt.Println("\nEncrypted Data : ")
		fmt.Printf("[")
		for i, val := range encrypted {
			if i == len(encrypted)-1 {
				fmt.Printf("0x%02X", val)
			} else {

				fmt.Printf("0x%02X, ", val)
			}
		}
		fmt.Printf("]\n")

		// fmt.Printf("[ 0x% X, ]\n", encrypted)
		fmt.Println(string(encrypted))

		sEnc := base64.StdEncoding.EncodeToString(encrypted)
		fmt.Println("\nbase64 Data :")

		fmt.Printf("[")
		for i, val := range sEnc {
			if i == len(sEnc)-1 {
				fmt.Printf("0x%02X", val)
			} else {

				fmt.Printf("0x%02X, ", val)
			}
		}
		fmt.Printf("]\n")
		fmt.Println(sEnc)

	}

}

func EncryptAESCFB(dst, src, key, iv []byte) error {
	aesBlockEncrypter, err := aes.NewCipher([]byte(key))
	if err != nil {
		return err
	}
	aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, iv)
	aesEncrypter.XORKeyStream(dst, src)
	return nil
}

func DecryptAESCFB(dst, src, key, iv []byte) error {
	aesBlockDecrypter, err := aes.NewCipher([]byte(key))
	if err != nil {
		return nil
	}
	aesDecrypter := cipher.NewCFBDecrypter(aesBlockDecrypter, iv)
	aesDecrypter.XORKeyStream(dst, src)
	return nil
}

실행 화면

테스트는 실행할 때, ABCD라는 키값을 넣고 1234ABC 라는 평문을 넣었다.

CFB 암호화와 추가로 Base64 인코딩을 했을때 까지 단계별로 확인할 수 있다.

출력은 Hex와 String으로 모두 확인 가능하다.

혹여나 다른 프로그램 코드에서 IP 나 Port 등과 같은 정보들을 암호화 해서 하드코딩 했는데

다음에 변경하여야 할 경우 혹은 테스트용으로 잠시 변경해야할 경우...

나름 유용하게 쓸 수 있지 않을까...? 는.... 내가 몇번 잘 썻다...ㅎ

끝!

 

반응형

KISA에서 제공하는 ARIA 암호화 예제를 이용한 간단한 암호화를 해보았다. 

 

16바이트로 딱 떨어지지 않는 데이터라도 제로 패딩을 하고 암호화를 하도록 기존의 함수를 조합한 정도뿐이지만...

개인적으로 함수 하나만 넣으면 결과를 얻을 수 있어 사용하기 편하게 만들었다.

 

기존 EncKeySetup 함수와 DeckeySetup 함수를 그대로 이용하였고 단순히 128비트 암호화를 사용하기 쉽게 함수만 2개 추가하였다 

 

사용한 master_key는 단순히 16 바이트로 단순히 1~16까지 넣었다. 

추가한 함수는 EnCrypt와 DeCrypt 이다. 

EnCrypt는 다음과 같다. 

암호화할 데이터와 결과를 얻을 버퍼, 평문의 길이를 넣으면 암호화된 결과의 길이가 리턴된다. 

 

DeCrypt는 다음과 같다. 

복호화 할 데이터와 결과를 얻을 버퍼, 복호화할 데이터의 길이를 넣으면 복호화 된 길이가 리턴된다.

 

해당 두 함수를 이용하여 ARIA128_test 함수를 만들었다

실행결과는 다음과 같다.

암호화를 하고 복호화를 해도 원래 데이터가 잘 나오는 것을 확인하였지만... 

검색을 통해 알아낸 ARIA 암. 복호화 모듈로 검증을 해보았다. 

 

EnCrypt
Decrypt

암.복호화 모두 일치하는 것을 확인을 했다.

 

더 많은 테스트가 필요하겠지만.. 일단은 성공...?

반응형

[]byte를 INT보다  HEX 데이터로 출력할 때가 생각보다 많은 것 같다. 

 

 

 위와 같은 iv []byte를 fmt.Println하면 아래와 같이 int형으로 출력이 된다. 

이를 hex형태로 보고 싶다면 예전에는 for문을 이용해서 아래와 같이 출력했다.....(미련하게...)

 

 

하지만 형식지정자를 사용하면 쉽게 출력 할 수 있었다.

좀 더 보기 좋게 하기 위해서 %뒤에 한칸 띄워서 각 바이트들이 띄워쓰기가 되도록 하고 \n을 넣어 마지막에 줄바꿈도 추가하였더니 

 

깔끔하게 출력되었다. 

 

엄청 기본적이고 쉬운 내용이였지만 그냥 지나쳐버려 비효율적인 방법을 반복하고 있었다......

반응형

Golang에서 제공되는 라이브러리를 이용하여 AES CBC 암호화를 하였다.

 

암호화의 기본 이론들이나 원리들은 잘 모르지만....

 

처음에 block size보다 작은 크기는 0을 추가하여 zero padding을 하고 암호화를 하였는데,

 

다시 복호화를 하였을 때 0이 남아있었다. (원래 그런건지.. 내가 잘못한건지...)

 

그래서 pkcs7Pad를 이용하였다.

 

패딩할때는 block size크기에 부족한 만큼 0 대신 그 크기를 넣었고, 

 

다시 읽을 때는 맨 마지막 바이트를 읽어 그 크기 만큼 빼고 읽었다. 

 

출력 결과

 

pkcs7Pad 패딩을 할 때는 빈 byte slice를 만들어 copy할 수도 있지만,  버퍼를 만들어 추가하는 형식으로 했다. 

pkcs7Unpad 언패딩은 암호문의 맨마지막 수를 읽고, 해당 수 만큼을 제외하고 나머지를 읽도록 하였다.

 

CBC 암호화전에 pkcs7Pad 해주고, 복호화하고 pkcs7Unpad 해주면 된다.

 

반응형

파일을 Hex array로 변환하고 C 헤더파일로 만드는 간단한 프로그램..

만들었지만 사용은 하지않고 있는 중.. 어딘가 사용되겠지..?

 

전체적인 구조는 다음과 같다. 

 

1. 변환하려는 파일을 Open한다. 

2. Output 파일에 먼저 헤더파일 형식(#include .. 등등 )을 Write 한다. 

3. 변환하려는 파일을 한 바이트씩 읽어 HEX형태로 Write한다. 

4. 끝!

 

전체적인 코드

 

반응형

+ Recent posts