- •Курсова робота
- •Календарний план
- •І. Опис предметної галузі
- •1.1 Огляд існуючих технологій
- •Усілякі засоби захисту конфіденційної інформації на комп'ютерах і в мережі за допомогою шифрування
- •Засоби аутентифікації
- •Антивірусний захист
- •Міжмережеве екранування
- •Захист програм від неліцензійного використання
- •Побудова аналогових і цифрових систем відеоспостереження
- •Організація обліку робочого часу та контролю місцезнаходження співробітників
- •1.2 Моделі і структури даних які використовуються в даній галузі
- •1.2.1 Моделі розмежованого доступу
- •1.2.2 Дискреційне управління доступом
- •1.2.3 Мандатне управління доступом
- •Класична мандатна модель Белла-ЛаПадули
- •Модель Біба
- •Модель безпеки військової системи передачі даних
- •Модель Кларка-Вілсона
- •Модель "Китайська стіна"
- •Модель Гогена-Мезігера
- •Сазерлендська модель захисту
- •Модель елементарного захисту
- •Модель гарантовано захищеної системи обробки інформації
- •Суб'єктно-об'єктна модель
- •1.3 Опис проблем захисту інформації
- •1.4 Висновок
- •Іі. Криптографічні Методи захисту інформації
- •2.1 Огляд сучасних методів захисту
- •Криптографія та кpиптоаналіз
- •Вимоги до криптосистем
- •2.2 Огляд існуючих програмних технологій
- •Порівняння можливостей шифрування архіваторів WinRar та WinZip
- •2.3 Опис прототипу Введення
- •Термінологія
- •Шифрування
- •Перетворення SubBytes
- •Дешифрування
- •III. Розробка власного програмного засобу, рішення
- •3.1 Опис власного методу розв’язання задач Визначення і допоміжні процедури
- •Допоміжні процедури
- •Шифрування
- •SubBytes()
- •ShiftRows()
- •MixColumns()
- •AddRoundKey()
- •Алгоритм обробки ключа
- •Алгоритм розширення ключа
- •Розшифрування
- •3.3.2 Структура програмних модулів
- •3.3.3 Опис програмних кодів
- •3.4 Висновок
- •Висновки
- •Література
- •Додаток а
- •Додаток б
- •Умови запуску програми
- •Робота з програмою
Додаток а
Реалізація алгоритму шифруванняAES-128
Текст програми
Листів 14
Розробник _____________________ Крохмаль Є.О.
Черкаси – 2011
aes.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Криптографія на JavaScript</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="ext.js"></script>
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" src="bits.js"></script>
<script type="text/javascript" src="gf28.js"></script>
<script type="text/javascript" src="aes.js"></script>
<script type="text/javascript">
function $(id)
{
return document.getElementById(id)
}
function tohexarray(str)
{
var s = '0123456789abcdef'
var ht = {}
for (var i = 0; i < 16; i++)
ht[s[i]] = i
var a = str.split(' ')
for (var i in a)
a[i] = 16 * ht[a[i][0]] + ht[a[i][1]]
return a
}
</script>
<style type="text/css">
body { font-family:calibri }
h1 { border-top: 1px solid lightblue; color:darkblue }
div.footnote { color:lightgray; position:absolute; right:1em; bottom:1em }
</style>
<body>
<h1>Кодування</h1>
<script type="text/javascript">
var ed = {}
ed.encrypt = function()
{
$('cipherinfo').innerHTML = ' '
var text = $('plaintext').value.bytes('ascii')
var pass = $('password').value.bytes('ascii')
var ciph = aes.encrypt(text, pass)
$('cipher').value = bits.hex(ciph, 1)
}
ed.decrypt = function()
{
var ciph = tohexarray($('cipher').value)
var pass = $('password').value.bytes('ascii')
var text = aes.decrypt(ciph, pass)
var s = ''.frombytes(text)
$('cipher').value = s
$('cipherinfo').innerHTML = s == $('plaintext').value ?
'Результат відповідає відкритому тексту'.bold().fontcolor('green') :
'Результат не відповідає відкритому тексту'.bold().fontcolor('red')
}
</script>
<table>
<tr><td>
<textarea cols="70" rows="10" id="plaintext">
In cryptography, the Advanced Encryption Standard (AES) is a symmetric-key encryption standard adopted by the U.S. government. The standard comprises three block ciphers, AES-128, AES-192 and AES-256, adopted from a larger collection originally published as Rijndael. Each of these ciphers has a 128-bit block size, with key sizes of 128, 192 and 256 bits, respectively. The AES ciphers have been analyzed extensively and are now used worldwide, as was the case with its predecessor, the Data Encryption Standard (DES).
</textarea>
<tr><td id="cipherinfo">
<tr><td>
<select id="cipheralg">
<option>AES-128</option>
</select>
<input size="40" id="password" value="pz-704"></input>
<input type="button" value="Закодувати" onclick="ed.encrypt()"></input>
<input type="button" value="Розкодувати" onclick="ed.decrypt()"></input>
<tr><td>
<textarea cols="70" rows="10" id="cipher"></textarea>
</table>
</body>
</html>
aes.js
// AES алгоритм
aes = {}
aes.nk = 4 // кількість 4-байтових слів в ключі
aes.nb = 4 // кількість колонок состояния
aes.nr = 10 // кількість раундів
aes.select = function(bits)
{
if (bits == 128)
{
aes.nk = 4
aes.nb = 4
aes.nr = 10
}
if (bits == 192)
{
aes.nk = 6
aes.nb = 4
aes.nr = 12
}
if (bits == 256)
{
aes.nk = 8
aes.nb = 4
aes.nr = 14
}
}
/* Кодує довільний рядок байтів з довільним паролем.
Повертає рядок з закодованими даними. Цей алгоритм використовує AES 128
оскільки MD5 повертає 128 - бітові хеші.
data масив байт
password масив байт */
aes.encrypt = function(data, password)
{
aes.select(128)
var hash = md5.hash(password)
var w = aes.keyexpansion(hash)
var length = bits.split(data.length, 16)
var result = aes.cipher(length, w)
for (var i = 0; i < data.length; i += 16)
{
var input = data.slice(i, i + 16)
while (input.length < 16)
input.push(0)
result = result.concat(aes.cipher(input, w))
}
return result
}
aes.decrypt = function(data, password)
{
aes.select(128)
var hash = md5.hash(password)
var w = aes.keyexpansion(hash)
var length = aes.invcipher(data.slice(0, 16), w)
var result = []
for (var i = 16; i < data.length; i += 16)
result = result.concat(aes.invcipher(data.slice(i, i + 16), w))
length = bits.merge(length)
if (length >= 0 && length <= result.length)
result.length = length
return result
}
/* Повертає елементи з таблиці S-Box.
аргумент повинен бути в діапазоні 0..255. */
aes.sbox = function(b)
{
var m = 0xf8
var r = 0
var q = gf.inv(b) || 0
for (var i = 0; i < 8; i++)
{
r = (r << 1) | bits.xorbits(q & m)
m = (m >> 1) | ((m & 1) << 7)
}
return r ^ 0x63
}
aes.invsbox = function(b)
{
for (var i = 0; i < 256; i++)
if (aes.sbox(i) == b)
return i
}
/* Змішує колонки з використанням вектора toprow
з 4 байтами. AES використовує дві величини toprow:
[02, 03, 01, 01] для шифрування
[0e, 0b, 0d, 09] для дешифрування */
aes.mixcolumns = function(s, toprow)
{
for (var c = 0; c < aes.nb; c++)
{
var col = []
for (var r = 0; r < 4; r++)
col[r] = s[r][c]
var k = toprow
for (var r = 0; r < 4; r++)
{
s[r][c] = aes.scalarmul(k, col)
k = array.ror(k, 1)
}
}
}
/* aes.cipher перетворює 16-байтовий вхід у 16-байтовий вихід.
input array[16] of byte
w array[4, aes.nb] of byte (взято з aes.keyexpansion)
output array[16] of byte */
aes.cipher = function(input, w)
{
var s = aes.input2state(input)
aes.addroundkey(s, w.slice(0, aes.nb))
for (var i = 1; i <= aes.nr - 1; i++)
{
aes.apply(aes.sbox, s)
aes.shiftrows(s)
aes.mixcolumns(s, [0x02, 003, 0x01, 0x01])
aes.addroundkey(s, w.slice(aes.nb * i, aes.nb * (i + 1)))
}
aes.apply(aes.sbox, s)
aes.shiftrows(s)
aes.addroundkey(s, w.slice(aes.nb * aes.nr, aes.nb * (aes.nr + 1)))
return aes.state2output(s)
}
aes.invcipher = function(input, w)
{
var s = aes.input2state(input)
aes.addroundkey(s, w.slice(aes.nb * aes.nr, aes.nb * (aes.nr + 1)))
for (var i = aes.nr - 1; i >= 1; i--)
{
aes.invshiftrows(s)
aes.apply(aes.invsbox, s)
aes.addroundkey(s, w.slice(aes.nb * i, aes.nb * (i + 1)))
aes.mixcolumns(s, [0x0e, 0x0b, 0x0d, 0x09])
}
aes.invshiftrows(s)
aes.apply(aes.invsbox, s)
aes.addroundkey(s, w.slice(0, aes.nb))
return aes.state2output(s)
}
/* Перетворює ключ в "ключ-специфікацію".
Цей "ключ-специфікація" пройдений на aes.cipher і aes.invcipher.
key array [aes.nk * 4] of byte
w array [4, aes.nb * (aes.nr + 1)] of byte */
aes.keyexpansion = function(key)
{
var w = []
for (var i = 0; i < aes.nk; i++)
w[i] = key.slice(4 * i, 4 * i + 4)
for (var i = aes.nk; i < aes.nb * (aes.nr + 1); i++)
{
var t = w[i - 1]
if (i % aes.nk == 0)
t = aes.xor(aes.sbox.map(array.rol(t, 1)), aes.rcon(i / aes.nk))
if (i % aes.nk == 4 && aes.nk > 6)
t = aes.sbox.map(t)
w[i] = aes.xor(w[i - aes.nk], t)
}
return w
}
aes.apply = function(f, s)
{
for (var c = 0; c < aes.nb; c++)
for (var r = 0; r < 4; r++)
s[r][c] = f(s[r][c])
}
aes.shiftrows = function(s)
{
for (var r = 0; r < 4; r++)
s[r] = array.rol(s[r], r)
}
aes.invshiftrows = function(s)
{
for (var r = 0; r < 4; r++)
s[r] = array.ror(s[r], r)
}
aes.addroundkey = function(s, w)
{
for (var c = 0; c < aes.nb; c++)
for (var r = 0; r < 4; r++)
s[r][c] = s[r][c] ^ w[c][r]
}
aes.xor = function(v1, v2)
{
var r = []
for (var i = 0; i < 4; i++)
r[i] = v1[i] ^ v2[i]
return r
}
aes.scalarmul = function(v1, v2)
{
var sum = 0
for (var i in v1)
sum ^= gf.mul(v1[i], v2[i])
return sum
}
aes.rcon = function(i)
{
var r = 1
for (var j = 1; j < i; j++)
r = gf.xtime(r)
return [r, 0, 0, 0]
}
aes.input2state = function(input)
{
var s = [[], [], [], []]
var i = 0
for (var c = 0; c < aes.nb; c++)
for (var r = 0; r < 4; r++)
{
s[r][c] = input[i]
i++
}
return s
}
aes.state2output = function(s)
{
var output = []
var i = 0
for (var c = 0; c < aes.nb; c++)
for (var r = 0; r < 4; r++)
{
output[i] = s[r][c]
i++
}
return output
}
aes.sbox = aes.sbox.cached()
aes.rcon = aes.rcon.cached()
aes.invsbox = aes.invsbox.cached()
bits.js
// Поразрядные действия.
bits =
{
concat: function(b0, b1, b2, b3)
{
return ((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | (b0 & 0xff)
},
split: function(int, bytes)
{
var res = []
for (var i = 0; i < bytes; i++)
{
res.push(int & 0xff)
int >>>= 8
}
return res
},
merge: function(bytes)
{
var res = 0
for (var i = bytes.length - 1; i >= 0; i--)
res = (res << 8) | bytes[i]
return res
},
// Зсув вліво на 32-bit ціле.
rol: function(value, shift)
{
var high = value >>> (32 - shift)
return (value << shift) | high
},
// Перетворення цілого в шістнадцяткові цифри.
hex: function(value, bytes, delim)
{
bytes = bytes || 4
if (delim === undefined)
delim = ' '
if (typeof value == 'object')
{
var r = []
for (var i in value)
r.push(bits.hex(value[i], bytes))
return r.join(delim)
}
var s = ''
while (bytes > 0)
{
bytes--
var h0 = value & 0x0f
var h1 = (value & 0xf0) >>> 4
s += bits.hexdigits.charAt(h1) + bits.hexdigits.charAt(h0)
value >>>= 8
}
return s
},
hexdigits: '0123456789abcdef',
revert: function(value, bytes)
{
bytes = bytes || 4
var r = 0
for (var i = 0; i < bytes; i++)
{
r <<= 8
r |= value & 0xff
value >>= 8
}
return r
},
xorbits: function(int, n)
{
n = n || 8
var res = 0
for(var i = 0; i < n; i++)
{
res ^= int & 1
int >>>= 1
}
return res
},
}
ext.js
// Розширення JavaScript-ових об'єктів.
array = {}
array.rol = function(a, n)
{
return a.slice(n, a.length).concat(a.slice(0, n))
}
array.ror = function(a, n)
{
return array.rol(a, a.length - n)
}
Function.prototype.cached = function()
{
var old = this
var cache = {}
return function(x)
{
if (cache[x] !== undefined)
return cache[x]
cache[x] = old(x)
return cache[x]
}
}
Function.prototype.map = function(list)
{
var res = {}
for (var i in list)
res[i] = this(list[i])
return res
}
String.prototype.bytes = function(mode)
{
var res = []
for (var i = 0; i < this.length; i++)
{
var c = this.charCodeAt(i)
var b0 = c % 256
var b1 = (c - b0) / 256
if (mode == 'ascii')
res.push(b0)
else
res.push(b0, b1)
}
return res
}
String.prototype.frombytes = function(bytes)
{
var res = ''
for (var i in bytes)
res += String.fromCharCode(bytes[i])
return res
}
gf28.js
// GF(2^8)
gf = {}
gf.xtime = function(b)
{
var highbit = b & 0x80
var shl = (b << 1) & 0xff
return highbit == 0 ? shl : shl ^ 0x1b
}
gf.mul = function(b1, b2)
{
var t = [b1]
var r = 0
for (var i = 1; i < 8; i++)
t[i] = gf.xtime(t[i - 1])
for (var i = 0; i < 8; i++)
if (b2 & (1 << i))
r ^= t[i]
return r
}
gf.inv = function(b)
{
for (var i = 0; i < 256; i++)
if (gf.mul(i, b) == 1)
return i
}
md5.js
// MD5 алгоритм
md5 = {}
md5.paddedlen = function(len)
{
var padded = ((len + 63) >>> 6) * 64
if (padded - len < 9)
padded += 64
return padded
}
md5.byteat = function(str, index)
{
var len = str.length
if (index < len)
return str[index]
if (index == len)
return 0x80
var n = md5.paddedlen(len)
if (index < n - 8)
return 0
var i = index
var b = 0
var m = len
while (i > n - 8)
{
i--
b = m & 0xff
m >>>= 8
}
m = (m << 3) | (b >>> 5)
return m & 0xff
}
md5.hash = function(str)
{
var F = function(x, y, z) { return x & y | ~x & z }
var G = function(x, y, z) { return x & z | y & ~z }
var H = function(x, y, z) { return x ^ y ^ z }
var I = function(x, y, z) { return y ^ (x | ~z) }
var S = function(i) { return md5.byteat(str, i) }
var M = function(i) { return bits.concat(S(i * 4), S(i * 4 + 1), S(i * 4 + 2), S(i * 4 + 3)) }
var X = []
var T = []
for (var i = 1; i <= 256; i++)
T[i] = Math.floor(0x100000000 * Math.abs(Math.sin(i)))
var W =
[
bits.concat(0x01, 0x23, 0x45, 0x67),
bits.concat(0x89, 0xab, 0xcd, 0xef),
bits.concat(0xfe, 0xdc, 0xba, 0x98),
bits.concat(0x76, 0x54, 0x32, 0x10),
]
// Вектор [A, B, C, D, k, s, i] відповідає [ABCD k s i] операції.
var rounds =
[
// Раунд F.
[
[ 0, 7],
[ 1, 12],
[ 2, 17],
[ 3, 22],
[ 4, 7],
[ 5, 12],
[ 6, 17],
[ 7, 22],
[ 8, 7],
[ 9, 12],
[10, 17],
[11, 22],
[12, 7],
[13, 12],
[14, 17],
[15, 22],
],
// Раунд G.
[
[ 1, 5],
[ 6, 9],
[11, 14],
[ 0, 20],
[ 5, 5],
[10, 9],
[15, 14],
[ 4, 20],
[ 9, 5],
[14, 9],
[ 3, 14],
[ 8, 20],
[13, 5],
[ 2, 9],
[ 7, 14],
[12, 20],
],
// Раунд H.
[
[ 5, 4],
[ 8, 11],
[11, 16],
[14, 23],
[ 1, 4],
[ 4, 11],
[ 7, 16],
[10, 23],
[13, 4],
[ 0, 11],
[ 3, 16],
[ 6, 23],
[ 9, 4],
[12, 11],
[15, 16],
[ 2, 23],
],
// Раунд I.
[
[ 0, 6],
[ 7, 10],
[14, 15],
[ 5, 21],
[12, 6],
[ 3, 10],
[10, 15],
[ 1, 21],
[ 8, 6],
[15, 10],
[ 6, 15],
[13, 21],
[ 4, 6],
[11, 10],
[ 2, 15],
[ 9, 21],
],
]
for (var i = 0; i < (md5.paddedlen(str.length) >> 6); i++)
{
for (var j = 0; j < 16; j++)
X[j] = M(i * 16 + j)
var Q = [W[0], W[1], W[2], W[3]]
for (var ri = 0; ri < 4; ri++)
for (var ti = 0; ti < 16; ti++)
{
var f = [F, G, H, I][ri]
var t = rounds[ri][ti]
var a = W[(0 - ti) & 3]
var b = W[(1 - ti) & 3]
var c = W[(2 - ti) & 3]
var d = W[(3 - ti) & 3]
var k = t[0]
var s = t[1]
var m = ri * 16 + ti + 1
a = b + bits.rol(a + X[k] + T[m] + f(b, c, d), s)
W[(0 - ti) & 3] = a
}
W = [W[0] + Q[0], W[1] + Q[1], W[2] + Q[2], W[3] + Q[3]]
}
var $ = function(i)
{
return bits.split(W[i], 4)
}
return [].concat($(0), $(1), $(2), $(3))
}
md5.selftest = function()
{
var pairs = [
['', 'd41d8cd98f00b204e9800998ecf8427e'],
['a', '0cc175b9c0f1b6a831c399e269772661'],
['abc', '900150983cd24fb0d6963f7d28e17f72'],
['message digest', 'f96b697d7cb7938d525a2f31aaf161d0'],
['abcdefghijklmnopqrstuvwxyz', 'c3fcd3d76192e4007dfb496cca67e13b'],
['ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'd174ab98d277d9f5a5611c2c9f419d9f']]
for (var i in pairs)
{
var message = pairs[i][0]
var digest = pairs[i][1]
var hash = md5.hash(message.bytes('ascii'))
if (bits.hex(hash, 1, '') != digest)
return false
}
return true
}