티스토리 뷰
이전에 라이브러리를 활용하여 이미지를 암호화하였습니다. 예전 암호분석경진대회 때 사용한 AES 함수를 이용해 이미지 암호화를 진행해보겠습니다.
1. 기본적으로 필요한 모듈과 함수들
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
sbox = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]
isbox = [82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]
gfp2 = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101, 155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165, 219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229]
gfp3 = [0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17, 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33, 96, 99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113, 80, 83, 86, 85, 92, 95, 90, 89, 72, 75, 78, 77, 68, 71, 66, 65, 192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209, 240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225, 160, 163, 166, 165, 172, 175, 170, 169, 184, 187, 190, 189, 180, 183, 178, 177, 144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129, 155, 152, 157, 158, 151, 148, 145, 146, 131, 128, 133, 134, 143, 140, 137, 138, 171, 168, 173, 174, 167, 164, 161, 162, 179, 176, 181, 182, 191, 188, 185, 186, 251, 248, 253, 254, 247, 244, 241, 242, 227, 224, 229, 230, 239, 236, 233, 234, 203, 200, 205, 206, 199, 196, 193, 194, 211, 208, 213, 214, 223, 220, 217, 218, 91, 88, 93, 94, 87, 84, 81, 82, 67, 64, 69, 70, 79, 76, 73, 74, 107, 104, 109, 110, 103, 100, 97, 98, 115, 112, 117, 118, 127, 124, 121, 122, 59, 56, 61, 62, 55, 52, 49, 50, 35, 32, 37, 38, 47, 44, 41, 42, 11, 8, 13, 14, 7, 4, 1, 2, 19, 16, 21, 22, 31, 28, 25, 26]
gfp9 = [0, 9, 18, 27, 36, 45, 54, 63, 72, 65, 90, 83, 108, 101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209, 202, 195, 252, 245, 238, 231, 59, 50, 41, 32, 31, 22, 13, 4, 115, 122, 97, 104, 87, 94, 69, 76, 171, 162, 185, 176, 143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118, 127, 100, 109, 82, 91, 64, 73, 62, 55, 44, 37, 26, 19, 8, 1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188, 181, 138, 131, 152, 145, 77, 68, 95, 86, 105, 96, 123, 114, 5, 12, 23, 30, 33, 40, 51, 58, 221, 212, 207, 198, 249, 240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229, 254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146, 155, 124, 117, 110, 103, 88, 81, 74, 67, 52, 61, 38, 47, 16, 25, 2, 11, 215, 222, 197, 204, 243, 250, 225, 232, 159, 150, 141, 132, 187, 178, 169, 160, 71, 78, 85, 92, 99, 106, 113, 120, 15, 6, 29, 20, 43, 34, 57, 48, 154, 147, 136, 129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237, 10, 3, 24, 17, 46, 39, 60, 53, 66, 75, 80, 89, 102, 111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224, 251, 242, 205, 196, 223, 214, 49, 56, 35, 42, 21, 28, 7, 14, 121, 112, 107, 98, 93, 84, 79, 70]
gfp11 = [0, 11, 22, 29, 44, 39, 58, 49, 88, 83, 78, 69, 116, 127, 98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227, 254, 245, 196, 207, 210, 217, 123, 112, 109, 102, 87, 92, 65, 74, 35, 40, 53, 62, 15, 4, 25, 18, 203, 192, 221, 214, 231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246, 253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137, 148, 159, 70, 77, 80, 91, 106, 97, 124, 119, 30, 21, 8, 3, 50, 57, 36, 47, 141, 134, 155, 144, 161, 170, 183, 188, 213, 222, 195, 200, 249, 242, 239, 228, 61, 54, 43, 32, 17, 26, 7, 12, 101, 110, 115, 120, 73, 66, 95, 84, 247, 252, 225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149, 158, 71, 76, 81, 90, 107, 96, 125, 118, 31, 20, 9, 2, 51, 56, 37, 46, 140, 135, 154, 145, 160, 171, 182, 189, 212, 223, 194, 201, 248, 243, 238, 229, 60, 55, 42, 33, 16, 27, 6, 13, 100, 111, 114, 121, 72, 67, 94, 85, 1, 10, 23, 28, 45, 38, 59, 48, 89, 82, 79, 68, 117, 126, 99, 104, 177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197, 206, 211, 216, 122, 113, 108, 103, 86, 93, 64, 75, 34, 41, 52, 63, 14, 5, 24, 19, 202, 193, 220, 215, 230, 237, 240, 251, 146, 153, 132, 143, 190, 181, 168, 163]
gfp13 = [0, 13, 26, 23, 52, 57, 46, 35, 104, 101, 114, 127, 92, 81, 70, 75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181, 162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149, 152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124, 95, 82, 69, 72, 3, 14, 25, 20, 55, 58, 45, 32, 109, 96, 119, 122, 89, 84, 67, 78, 5, 8, 31, 18, 49, 60, 43, 38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207, 194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245, 190, 179, 164, 169, 138, 135, 144, 157, 6, 11, 28, 17, 50, 63, 40, 37, 110, 99, 116, 121, 90, 87, 64, 77, 218, 215, 192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156, 145, 10, 7, 16, 29, 62, 51, 36, 41, 98, 111, 120, 117, 86, 91, 76, 65, 97, 108, 123, 118, 85, 88, 79, 66, 9, 4, 19, 30, 61, 48, 39, 42, 177, 188, 171, 166, 133, 136, 159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173, 160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252, 103, 106, 125, 112, 83, 94, 73, 68, 15, 2, 21, 24, 59, 54, 33, 44, 12, 1, 22, 27, 56, 53, 34, 47, 100, 105, 126, 115, 80, 93, 74, 71, 220, 209, 198, 203, 232, 229, 242, 255, 180, 185, 174, 163, 128, 141, 154, 151]
gfp14 = [0, 14, 28, 18, 56, 54, 36, 42, 112, 126, 108, 98, 72, 70, 84, 90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158, 140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255, 241, 171, 165, 183, 185, 147, 157, 143, 129, 59, 53, 39, 41, 3, 13, 31, 17, 75, 69, 87, 89, 115, 125, 111, 97, 173, 163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235, 249, 247, 77, 67, 81, 95, 117, 123, 105, 103, 61, 51, 33, 47, 5, 11, 25, 23, 118, 120, 106, 100, 78, 64, 82, 92, 6, 8, 26, 20, 62, 48, 34, 44, 150, 152, 138, 132, 174, 160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204, 65, 79, 93, 83, 121, 119, 101, 107, 49, 63, 45, 35, 9, 7, 21, 27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195, 233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234, 228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104, 66, 76, 94, 80, 10, 4, 22, 24, 50, 60, 46, 32, 236, 226, 240, 254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182, 12, 2, 16, 30, 52, 58, 40, 38, 124, 114, 96, 110, 68, 74, 88, 86, 55, 57, 43, 37, 15, 1, 19, 29, 71, 73, 91, 85, 127, 113, 99, 109, 215, 217, 203, 197, 239, 225, 243, 253, 167, 169, 187, 181, 159, 145, 131, 141]
Rcon = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145, 57, 114, 228, 211, 189, 97, 194, 159, 37, 74, 148, 51, 102, 204, 131, 29, 58, 116, 232, 203, 141]
HW=[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8]
def RotWord(word):
return word[1:] + word[0:1]
def SubWord(word):
return [sbox[byte] for byte in word]
def SubBytes(state):
return [[sbox[byte] for byte in word] for word in state]
def InvSubBytes(state):
return [[isbox[byte] for byte in word] for word in state]
def ShiftRows(state):
Nb = len(state)
n = [word[:] for word in state]
for i in range(Nb):
for j in range(4):
n[i][j] = state[(i+j) % Nb][j]
return n
def InvShiftRows(state):
Nb = len(state)
n = [word[:] for word in state]
for i in range(Nb):
for j in range(4):
n[i][j] = state[(i-j) % Nb][j]
return n
def MixColumns(state):
Nb = len(state)
n = [word[:] for word in state]
for i in range(Nb):
n[i][0] = (gfp2[state[i][0]] ^ gfp3[state[i][1]]
^ state[i][2] ^ state[i][3])
n[i][1] = (state[i][0] ^ gfp2[state[i][1]]
^ gfp3[state[i][2]] ^ state[i][3])
n[i][2] = (state[i][0] ^ state[i][1]
^ gfp2[state[i][2]] ^ gfp3[state[i][3]])
n[i][3] = (gfp3[state[i][0]] ^ state[i][1]
^ state[i][2] ^ gfp2[state[i][3]])
return n
def InvMixColumns(state):
Nb = len(state)
n = [word[:] for word in state]
for i in range(Nb):
n[i][0] = (gfp14[state[i][0]] ^ gfp11[state[i][1]]
^ gfp13[state[i][2]] ^ gfp9[state[i][3]])
n[i][1] = (gfp9[state[i][0]] ^ gfp14[state[i][1]]
^ gfp11[state[i][2]] ^ gfp13[state[i][3]])
n[i][2] = (gfp13[state[i][0]] ^ gfp9[state[i][1]]
^ gfp14[state[i][2]] ^ gfp11[state[i][3]])
n[i][3] = (gfp11[state[i][0]] ^ gfp13[state[i][1]]
^ gfp9[state[i][2]] ^ gfp14[state[i][3]])
return n
예전에는 numpy를 잘 쓸 줄 몰라 list를 이용해 구현했었는데, 나중에 위의 함수들도 numpy를 이용해 정리를 해야겠습니다. 아무래도 행렬 연산과 같은 것은 list를 이용한 것보다는 array와 numpy 메서드를 이용하는 것이 더 빠르기에 올해 대회 참가 때는 정리한 함수를 사용할 것입니다.
2. 암호 알고리즘 (AES128)
- ECB
def AES128_ECB(plain_block, whole_key, round=10):
# plain_block 위치에 4*4 리스트 넣기
# 한 블럭당 16byte
cipher_block = copy.deepcopy(plain_block)
for i in range(4):
for j in range(4):
cipher_block[i][j] ^= whole_key[0][i][j]
for i in range(1,round+1):
cipher_block = SubBytes(cipher_block)
cipher_block = ShiftRows(cipher_block)
if i != round:
cipher_block = MixColumns(cipher_block)
for j in range(4):
for k in range(4):
cipher_block[j][k] ^= whole_key[i][j][k]
return cipher_block
- CBC
def AES128_CBC(plain_block, whole_key, round=10, iv=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]):
# plain_block 위치에 4*4 리스트 넣기
# 한 블럭당 16byte
cipher_block = copy.deepcopy(plain_block)
for i in range(4):
for j in range(4):
cipher_block[i][j] ^= iv[i][j]
for i in range(4):
for j in range(4):
cipher_block[i][j] ^= whole_key[0][i][j]
for i in range(1,round+1):
cipher_block = SubBytes(cipher_block)
cipher_block = ShiftRows(cipher_block)
if i != round:
cipher_block = MixColumns(cipher_block)
for j in range(4):
for k in range(4):
cipher_block[j][k] ^= whole_key[i][j][k]
return cipher_block
- OFB
def AES128_OFB(plain_block, whole_key, round=10, iv=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]):
# plain_block 위치에 4*4 리스트 넣기
# 한 블럭당 16byte
cipher_block = copy.deepcopy(iv)
for i in range(4):
for j in range(4):
cipher_block[i][j] ^= whole_key[0][i][j]
for i in range(1,round+1):
cipher_block = SubBytes(cipher_block)
cipher_block = ShiftRows(cipher_block)
if i != round:
cipher_block = MixColumns(cipher_block)
for j in range(4):
for k in range(4):
cipher_block[j][k] ^= whole_key[i][j][k]
input_vec = copy.deepcopy(cipher_block)
for i in range(4):
for j in range(4):
cipher_block[i][j] ^= plain_block[i][j]
return cipher_block, input_vec
모드 별로 암호화 진행 시 이미지의 차이도 있겠지만, 라운드 별 암호화 진행 시 차이가 있을 지 궁금해 라운드 별로 암호화 시킬 수 있도록 만들었습니다.
(돌려본 결과 차이는 없었다.)
다른 모드들도 있지만, ECB 외에는 육안으로 크게 차이가 나지 않아, CBC와 OFB만 추가로 구현했습니다.
그리고 Initail Vector는 default 값을 0 으로 설정했습니다.
AES 암호의 로직을 그대로 따라가면 되므로 크게 어렵지 않습니다.
AES : ghqls0210.tistory.com/40
3. 암호화
import copy
arr = []
for i in range(1, 1001):
img = Image.open('./data_img/%d.jpg' %i)
arr.append(copy.deepcopy(np.array(img)))
import random
import string
def key_generator(size = 16, chars = string.ascii_lowercase):
return ''.join(random.choice(chars) for _ in range(size))
def make_base_key(key):
base_key = [[0,0,0,0] for _ in range(4)]
for i in range(4):
for j in range(4):
base_key[i][j] = ord(key[4*i+j])
return base_key
def make_whole_key(base_key):
# AES128에서 key는 128bit (16byte)
# key : 4*4로 받기
# 10라운드 다 만들기, 처음에 더해주는 것까지 해서 총 11개
whole_key = []
w = copy.deepcopy(base_key)
whole_key.append(copy.deepcopy(w))
for i in range(1,11):
t = SubWord(RotWord(w[3]))
for j in range(4):
t[j] ^= Rcon[i]
for j in range(4):
w[0][j] ^= t[j]
for j in range(4):
w[1][j] ^= w[0][j]
for j in range(4):
w[2][j] ^= w[1][j]
for j in range(4):
w[3][j] ^= w[2][j]
whole_key.append(copy.deepcopy(w))
return whole_key
암호화 시킬 이미지를 불러오고, AES128에 필요한 마스터키 생성 및 라운드별 키를 만들어주는 함수입니다.
key_generator : 랜덤한 알파벳 조합으로 16byte 암호 생성
make_base_key : 생성된 키를 계산가능하게 조절 (마스터키)
make_whole_key : 전 라운드의 키를 생성
마지막으로, 이미지를 불러와 위 함수들의 형식에 맞게 변환 후, 암호화를 시켜 저장합니다.
암호화된 이미지는 모두 256 * 256 pixel로 맞췄습니다.
idx = 1
for Arr in arr:
key = key_generator()
print(key)
base_key = make_base_key(key)
print(base_key)
whole_key = make_whole_key(base_key)
print(whole_key)
print(len(whole_key[0]))
print(Arr.shape)
iv = [[0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00]]
ecb = Arr.tolist()
cbc = Arr.tolist()
ofb = Arr.tolist()
cipher_ecb = []
for i in range(3):
whole = [[0 for _ in range(256)] for __ in range(256)] # whole : 256 * 256
channel = np.array(ecb[i])
# channel : 256 * 256
for j in range(0,len(channel), 4):
for k in range(0,len(channel[j]), 4):
block = channel[j:j+4, k:k+4]
block = block.tolist()
block = AES128_ECB(block, whole_key, round=10)
for y in range(4):
for x in range(4):
whole[j+y][k+x] = block[y][x]
cipher_ecb.append(whole)
cipher_ecb = np.array(cipher_ecb)
cipher_ecb = cipher_ecb.transpose(1,2,0)
cipher_ecb = cipher_ecb.astype(np.uint8)
cipher_ecb = Image.fromarray(cipher_ecb)
cipher_ecb.save('./ECB_img/ecb%d.jpg' %idx)
cipher_cbc = []
IV = copy.deepcopy(iv)
for i in range(3):
whole = [[0 for _ in range(256)] for __ in range(256)] # whole : 256 * 256
channel = np.array(cbc[i])
# channel : 256 * 256
for j in range(0,len(channel), 4):
for k in range(0,len(channel[j]), 4):
block = channel[j:j+4, k:k+4]
block = block.tolist()
block = AES128_CBC(block, whole_key, round=10, iv=IV)
for y in range(4):
for x in range(4):
whole[j+y][k+x] = block[y][x]
IV[y][x] = block[y][x]
cipher_cbc.append(whole)
cipher_cbc = np.array(cipher_cbc)
cipher_cbc = cipher_cbc.transpose(1,2,0)
cipher_cbc = cipher_cbc.astype(np.uint8)
cipher_cbc = Image.fromarray(cipher_cbc)
cipher_cbc.save('./CBC_img/cbc%d.jpg' %idx)
cipher_ofb = []
IV = copy.deepcopy(iv)
for i in range(3):
whole = [[0 for _ in range(256)] for __ in range(256)] # whole : 256 * 256
channel = np.array(ofb[i])
# channel : 256 * 256
for j in range(0,len(channel), 4):
for k in range(0,len(channel[j]), 4):
block = channel[j:j+4, k:k+4]
block = block.tolist()
block, input_vec = AES128_OFB(block, whole_key, round=10, iv=IV)
for y in range(4):
for x in range(4):
whole[j+y][k+x] = block[y][x]
IV[y][x] = input_vec[y][x]
cipher_ofb.append(whole)
cipher_ofb = np.array(cipher_ofb)
cipher_ofb = cipher_ofb.transpose(1,2,0)
cipher_ofb = cipher_ofb.astype(np.uint8)
cipher_ofb = Image.fromarray(cipher_ofb)
cipher_ofb.save('./OFB_img/ofb%d.jpg' %idx)
idx += 1
4. 결과
사실상 ECB 말고는 형태도 알 수 없고, 모드 자체도 구분 불가능합니다.
5. 마무리
이번 프로젝트를 진행하면서 새롭게 알게 된 점은 라운드 별로 암호화를 진행하여도, ECB를 제외하고는 어떤 모드도 구분이 불가능하다는 것입니다. 즉, 1라운드를 암호화하나, 10라운드를 암호화하나 눈에 보이는 것은 비슷합니다. (컴퓨터는 어떻게 인식할지는 아직은 모르겠다....)
또한, ECB 모드라 하여도, 음영의 차이가 뚜렷한 이미지나, 패턴의 반복이 심하게 이루어진 (AES블록 단위보다 작게) 경우는 ECB 모드로 암호화하여도 위의 CBC나 OFB와 유사한 모습을 보입니다.
AES 블록보다 적은 간격 (4*4 byte 블록이므로, 1,2 byte 간격으로 차이 발생하는 이미지) 에서 차이가 나면, 아무리 블록 별로 같은 값으로 암호화 되는 ECB라도 이미지 자체의 값이 달라지기 때문에 형태가 나타나지 않습니다.
'암호학 > 자기주도연구 프로젝트' 카테고리의 다른 글
DES 이미지 암호화 딥러닝 학습 (16round) (0) | 2021.05.05 |
---|---|
이미지 암호화 / DES (single) 활용한 이미지 암호화 (0) | 2021.04.09 |
암호화 이미지 딥러닝 모델링 (AES128) (0) | 2021.04.01 |
구글 이미지 크롤링 (0) | 2021.04.01 |
이미지 암호화 - python AES 라이브러리 사용 (9) | 2021.03.26 |