자바 JCE 에서의 AES 관련 질문

eno의 이미지

JCE를 이용해 AES 암 복호화를 구현을 했습니다.
그런데 문제가

긴 문자열을 암호화 한 값 중 일부만 다른 값으로 변조하여
복호화를 한 경우 일부만 문자열이 깨질 뿐 나머지는 정상적으로 복호화가 됩니다.

예를들어

평문

144662ba1c07a11633c051c42b77d455b82b9613aa2181f9cda9941d53e44389

암호화 하면 아래의 암호문을 얻어옵니다.

9d886adfea492e0f503a98e0f80d33d6c6eafeeb9a360e44fdc392bcb9249db2bf700945c65ea7018fa60d5c403f6b5b4965d5212a3e1cd74e13f50bad080e7d5015133e6f78ce131106f5442000aac1

이때 위 암호문 중 첫 글자 9만 변조하여 복호화를 했다면 완전히 깨져서 나와야 정상 아닙니까

그런데 아래처럼 일부만 깨지고 잘 복호화 되어 나옵니다.

@#!!@#$!@#$!@#!@a33c051c42b77d455b82b9613aa2181f9cda9941d53e44389
(실제는 더 이상하게 깨져서 나오나 이 게시판에서 깨진글자가 인식이 안되 저렇게 대체합니다.)

즉 평문 33c051c~ 부터는 잘 복호화 되서 나옵니다.

글자가 완전히 깨져서 나올 수 있는 방법은 없는건가요?

아래는 소스 전문입니다.
소스는 아래 URL을 참고했습니다.
http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html

-------------------------------------------------------------------
// 암호화
public String encrypt(String plainText) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);

byte[] raw = new byte[] { -121, 7, 49, 40, -95, -16, -118, -85, 28, -67, -63, 2, 101, 56, -72, 111};
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");

cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
return asHex(encrypted);

}

// 복호화
public String decrypt(String cipherText) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);

byte[] raw = new byte[] { -121, 7, 49, 40, -95, -16, -118, -85, 28, -67, -63, 2, 101, 56, -72, 111};
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");

cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(fromString(cipherText));
String originalString = new String(original);
return originalString;

}

private static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;

for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) strbuf.append("0");

strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}

return strbuf.toString();
}

private static byte[] fromString(String hex) {
int len = hex.length();
byte[] buf = new byte[((len + 1) / 2)];

int i = 0, j = 0;
if ((len % 2) == 1)
buf[j++] = (byte) fromDigit(hex.charAt(i++));

while (i < len) {
buf[j++] =
(byte) ((fromDigit(hex.charAt(i++)) << 4)
| fromDigit(hex.charAt(i++)));
}
return buf;
}

private static int fromDigit(char ch) {
if (ch >= '0' && ch <= '9')
return ch - '0';
if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;

throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
}

익명사용자의 이미지

AES 알고리즘은 블록 암호 알고리즘입니다. 따라서 별도의 운영모드 없이 암호화 하게 되면 말씀하신대로 암호화된 문자열중 일부만 변경하였을 때 변경된 부분의 암호만 복호화가 되지 않고 나머지는 정상적으로 복호화 하게 됩니다.

이럴 경우 암호의 패턴이 쉽게 드러날 수 있으므로 AES 암호의 강도가 유지된다고 보기 힘들지요. 그래서 CBC 모드 같은 것들을 사용하게 되는데 첫 블록을 암호화 하고 이를 그 다음 블록의 암호화 블록과 XOR 시키고 이를 다시 그 다음 암호화 블록과 XOR 시키는 등의 방식으로 마지막 블록까지 이어 나가게 됩니다. 그리고 제일 처음 암호화 되는 블록은 보통 임의의 이니셜 벡터와 암호화 시키게 되구요.

복호화 할 때에는 XOR 의 특징을 이용해서 a xor b xor b=a
CBC 모드 이외에도 여러가지 운영모드가 존재하고 블록 암화 알고리즘을 효과적으로 이용하기 위해서는 이런 운영모드들을 잘 이해하는게 중요합니다.

IsExist의 이미지

블럭 암호화의 특성상 암/복호화가 블럭 단위로 이루어집니다.
예를들어 16바이트 단위로 암호화를 하는 알고리즘을 사용할 경우
처음 16바이트가 암호화되고 그다음 16바이트가 암호화 됩니다.
헌데 동작모드에 따라서 이들 블럭들을 다루는 방식이 틀려집니다.

모드에 대해서 살펴보면 답을 얻을 수 있을 겁니다.

Cipher c1 = Cipher.getInstance("AES/CBC/PKCS5Padding");

http://java.sun.com/j2se/1.5.0/docs/guide/security/jce/JCERefGuide.html#SimpleEncrEx
---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.