我想在python中實現Shamir Secret Sharing Sceme,我需要詢問用戶密碼,然後用sha256獲取哈希碼,但是當我嘗試使用它作爲參數時對於AES來說,密鑰的長度必須是16,24或32位,是不是會返回一個32字節的字符串?使用sha256密碼AES加密
這裏是我的代碼:
import getpass
import hashlib
import random
import operator
from functools import reduce
import sys
import os
from Crypto.Cipher import AES
p= 208351617316091241234326746312124448251235562226470491514186331217050270460481
points= []
## Class Prime
#
# Class that represents integers modulo p, it is built from a non negative integer
# , comes with its own implementations of basic operations like sum, multiplication
# and division, the division is calculated ith the extended euclidean algorithm.
class Prime(object):
## The constructor
def __init__(self, n):
self.n = n % p
def __add__(self, other): return Prime(self.n + other.n)
def __sub__(self, other): return Prime(self.n - other.n)
def __mul__(self, other): return Prime(self.n * other.n)
def __pow__(self, x): return Prime(self.n**x)
def __truediv__(self, other): return self * other.inverse()
def __div__(self, other): return self * other.inverse()
def __neg__(self): return Prime(-self.n)
def __eq__(self, other): return isinstance(other, Prime) and self.n == other.n
def __abs__(self): return abs(self.n)
def __str__(self): return str(self.n)
def __divmod__(self, divisor):
q,r = divmod(self.n, divisor.n)
return (Prime(q), Prime(r))
def EuclideanAlgorithm(a, b):
if abs(b) > abs(a):
(x,y,d) = EuclideanAlgorithm(b, a)
return (y,x,d)
if abs(b) == 0:
return (1, 0, a)
x1, x2, y1, y2 = 0, 1, 1, 0
while abs(b) > 0:
q, r = divmod(a,b)
x = x2 - q*x1
y = y2 - q*y1
a, b, x2, x1, y2, y1 = b, r, x1, x, y1, y
return (x2, y2, a)
def inverse(self):
(x,y,d)= EuclideanAlgorithm(self.n, p)
return Prime(x)
## Class Polynomial
#
# Class that represents a polynomial, it is built from a list of coefficients
# comes with a call method to evaluate the polynomial in a value "x", and has
# a reduced lagrange method that gets the constant value of a polynomial from
# a set of points
class Polynomial(object):
## The constructor
def __init__(self, coefficients):
self.coeff= coefficients
def __call__(self, x):
n = 0
tmp = Prime(0)
for i in self.coeff:
tmp = tmp + (i*(x**n))
n += 1
return tmp
def lagrange(points):
product= functools.reduce(operator.mul, points, 1)
sum= 0
for x in points:
p= 1
for y in points:
if x!= y:
p= p*(x-y)
sum+= poly(x)/(-x*p)
return sum
## Ask the user for a password and gets its hash code with sha256
def password():
p= getpass.getpass()
h= hashlib.sha256(p)
s= h.hexdigest()
constant= int(s, 16)
return constant
## Makes a polynomial with random coefficients and a fixed constant value, and
# evaluates it with n random values an writes the results to a file.
# @param constant The constant value of the polynomial.
# @param evaluations The number of evaluations to be made.
# @param degree The degree of the polynomial.
# @param out_fileName The name of the file where the evaluations are going
# to be written.
# \pre The constant, evaluations and degree must be positive integers.
# \post If no error occurs then, the file whose name was passed will contain
# n evaluations of the polynomial.
def makeKeys(constant, evaluations, degree, out_fileName):
coeffs= []
coeffs.append(Prime(constant))
for x in range(1, degree):
randomc= random.randint(1, p - 1)
coeffs.append(Prime(randomc))
poly= Polynomial(coeffs)
file= open(out_fileName, "w")
for x in range(1, evaluations + 1):
randomi= random.randint(1, p - 1)
points.append(randomi)
e= poly(Prime(randomi))
file.write("(%d, %d)\n" % (randomi, e.n))
file.close()
def encrypt(key, in_fileName, out_fileName):
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_ECB, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt(ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_ECB, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
def decrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(ciphertext, key)
with open(file_name[:-4], 'wb') as fo:
fo.write(dec)
你舉的例子是大到能夠理解。請提供一個最小的答案。例如。只需調用get password函數和AES即可。 –