def _hashPassword(self, password, scheme, salt=None): """ Return hashed password (including salt). """ scheme = scheme.lower() if not scheme in AVAIL_USERPASSWORD_SCHEMES.keys(): raise ValueError, 'Hashing scheme %s not supported for class %s.' % ( scheme, self.__class__.__name__) raise ValueError, 'Hashing scheme %s not supported.' % (scheme) if salt is None: if scheme == 'crypt': salt = GenerateSalt(saltLen=2, saltAlphabet=CRYPT_ALPHABET) elif scheme in ['smd5', 'ssha']: salt = GenerateSalt(saltLen=8, saltAlphabet=None) else: salt = '' if scheme == 'crypt': return crypt.crypt(password, salt) elif scheme in ['md5', 'smd5']: return base64.encodestring( hash_md5(password + salt).digest() + salt).strip() elif scheme in ['sha', 'ssha']: return base64.encodestring( hash_sha1(password + salt).digest() + salt).strip() else: return password
def get_file_md5(self, filename): if not os.path.isfile(filename): return myHash = hash_md5() f = open(filename, 'rb') while True: b = f.read(8096) if not b: break myHash.update(b) f.close() return myHash.hexdigest()
def _hashPassword(self, password, scheme, salt=None): """ Returns tuple of hashed password (including salt), salt. """ scheme = scheme.lower() if not scheme in AVAIL_AUTHPASSWORD_SCHEMES.keys(): raise ValueError, 'Hashing scheme %s not supported for class %s.' % ( scheme, self.__class__.__name__) if salt is None: salt = GenerateSalt(saltLen=16, saltAlphabet=None) if scheme == 'md5': return hash_md5(password + salt).digest(), salt elif scheme == 'sha1': return hash_sha1(password + salt).digest(), salt else: raise ValueError, 'Hashing scheme %s not implemented for class %s.' % ( scheme, self.__class__.__name__)
def login(): session.permanent = True if request.method == 'GET': return render_template('login.html') if request.method == 'POST': user_name = request.form.get('user_name') password = request.form.get('password') # 判断用户名和密码是否填写 if not all([user_name, password]): msg = '* 请填写好完整的信息' return render_template('login.html', msg=msg) # 核对用户名和密码是否一致 # 首先对密码进行数字摘要 h_md5 = hash_md5() h_md5.update(password.encode('utf-8')) # 需要将字符串进行编码,编码成二进制数据 password_md5_str = h_md5.hexdigest() # 获取16进制的摘要作为保存的密码 user = User.query.filter_by(user_name=user_name, password=password_md5_str).first() # 如果用户名和密码一致 if user: # 向session中写入相应的数据 session['user_id'] = user.id session['role'] = user.role session['username'] = user.user_name session['head_img'] = user.head_img session['balance'] = float(user.balance.quantize(Decimal('0.00'))) session['born_date'] = user.born_date session['phone'] = user.phone session['sex'] = user.sex if session['role'] == 1: return redirect(url_for('main.admin')) return redirect(url_for('users.index')) # 如果用户名和密码不一致返回登录页面,并给提示信息 else: msg = '* 用户名或者密码不正确' return render_template('login.html', msg=msg)
def register(): if request.method == 'GET': return render_template('login.html') if request.method == 'POST': # 获取用户填写的信息 user_name = request.form.get('user_name') pwd1 = request.form.get('pwd1') pwd2 = request.form.get('pwd2') base_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'static\\images\\head_img') head_img = "head_img.png" # head_img = request.form.get('head_img') real_name = request.form.get('real_name') sex = request.form.get('sex') born_date = request.form.get('born_date') phone = request.form.get('phone') # 定义个变量来控制过滤用户填写的信息 msg, flag = '', True # 判断用户是否信息都填写了.(all()函数可以判断用户填写的字段是否有空) if not all([user_name, pwd1, pwd2, real_name, sex, born_date, phone]): msg, flag = '* 请填写完整信息', False return render_template('login.html', msg=msg) # 判断用户名是长度是否大于20 if len(user_name) > 20: msg, flag = '* 用户名太长', False # 判断两次填写的密码是否一致 if pwd1 != pwd2: msg, flag = '* 两次密码不一致', False # 判断真实名字长度是否大于20 if len(real_name) > 20: msg, flag = '* 真实名太长', False # 判断电话号码长度是否合法 if len(phone) != 11: msg, flag = '电话号码非法', False # 判断电话号码开始一位是否合法 if phone[0] != '1': msg, flag = '电话号码非法', False # 如果上面的检查有任意一项没有通过就返回注册页面,并提示响应的信息 if not flag: return render_template('login.html', msg=msg) # 核对输入的用户是否已经被注册了 u = User.query.filter(User.user_name == real_name).first() # 判断用户名是否已经存在 if u: msg = '用户名已经存在' return render_template('login.html', msg=msg) # 上面的验证全部通过后就开始创建新用户 # 首先加密获取密码摘要 # MD5 加密 h_md5 = hash_md5() h_md5.update(pwd1.encode('utf-8')) # 需要将字符串进行编码,编码成二进制数据 pwd1_md5_str = h_md5.hexdigest() # 获取16进制的摘要作为保存的密码 # print('MD5生成摘要结果:', pwd1_md5_str) # 输出结果 user = User(user_name=user_name, password=str(pwd1_md5_str), real_name=real_name, head_img=head_img, sex=sex, born_date=born_date, phone=phone) # 保存注册的用户 user.save() # print(msg) # 跳转到登录页面 return redirect(url_for('users.login'))
def md5(password: str) -> str: m = hash_md5() m.update(password.encode()) return m.hexdigest()
def decrypt_file(input_file: str, output_file: str, crypter_key: str, block_size: int = DEFAULT_BLOCK_SIZE) -> bool: """ Decrypt a file using AES/HMAC MD5 using the provided Key :param input_file: file to decrypt :param output_file: where to write the decrypted file content :param crypter_key: key to use to decrypt data :type input_file: str :type output_file: str :type crypter_key: str :returns bool """ #Crypter key to bytes crypter_key = crypter_key.encode() try: ihnd = open(input_file, 'rb') ihnd.seek(0, 2) filesize = ihnd.tell() - 8 # Remove filesize if filesize < 32: print_err("File is too short to be decrypted") return False if filesize % 16 != 0: # Remove filesize print_err("File size must be multiple of 16") return False ihnd.seek(0, 0) #Read first 16 bytes (IV) iv = ihnd.read(16) print_info("IV is %s" % hexlify(iv)) #AES key is MD5sum between the crypter key and the IV digest = hash_md5() digest.update(iv) digest.update(crypter_key) aes_key = digest.digest() print_info("AES key is %s" % hexlify(aes_key)) #Init AES crypter crypter = AES.new(aes_key, AES.MODE_CBC, iv) #Prepare key_ipad and k_opad, I don't know what they are... key_opad = bytearray() key_ipad = bytearray() for i in range(64): key_ipad.append(0x36) key_opad.append(0x5C) for i in range(16): key_ipad[i] = 0x36 ^ aes_key[i] key_opad[i] = 0x5C ^ aes_key[i] datasize = filesize - 32 #filesize - IV - HMAC #Get HMAC ihnd.seek(-24, 2) #Last 24 bytes final_hmac_in = ihnd.read(16) lastn = ihnd.read(8) # Data size native_data_size = int.from_bytes(lastn, "big") print_info("Decrypted file size will be %d (read from last 8 bytes)" % native_data_size) #Verify HMAC before decrypting digest = hash_md5() digest.update(key_ipad) #Return to 16th byte ihnd.seek(16, 0) #Digest while ihnd.tell( ) <= datasize: # <= cause we're already at 16 (imagine if filesize were 48, datasize would be 16) digest.update(ihnd.read(16)) final_hmac = digest.digest() #Opad + md5sum(ipad, file) digest = hash_md5() digest.update(key_opad) digest.update(final_hmac) final_hmac = digest.digest() #Compare HMAC print_info("HMAC from file: %s" % hexlify(final_hmac_in)) print_info("HMAC calculated: %s" % hexlify(final_hmac)) if final_hmac != final_hmac_in: print_err("HMAC doesn't match") return False #Return to 16th byte ihnd.seek(16, 0) final_size = 0 #Read and decrypt try: #Open output file ohnd = open(output_file, "wb") offset = 0 progress = 0 while offset < datasize: # <= cause we're already at 16 (imagine if filesize were 48, datasize would be 16) input_block = bytearray() input_block.extend(ihnd.read(block_size)) #Encrypt block and append to encrypted data decrypted_block = crypter.decrypt(bytes(input_block)) #Write decrypted block (only block length) offset += block_size if native_data_size > 0 and offset == datasize: #Write remaining bytes # Remaining bytes remaining_bytes = native_data_size % block_size ohnd.write(decrypted_block[0:remaining_bytes]) final_size += remaining_bytes else: ohnd.write(decrypted_block) #Write entire block otherwise final_size += block_size progress = (offset * 100) / datasize print_progress_bar(progress, 100) #Close file ohnd.close() except IOError as err: print_err("IOError: %s" % err) return False print_info("Data decrypted (%d bytes)" % final_size) #Close file ihnd.close() except IOError as err: print_err("Could not open input file %s: %s" % (input_file, err)) return False return True
def encrypt_file(input_file: str, output_file: str, crypter_key: str, block_size: int = DEFAULT_BLOCK_SIZE) -> bool: """ Encrypt a file using AES/HMAC MD5 using the provided Key :param input_file: file to encrypt :param output_file: where to write the encrypted file content :param crypter_key: key to use to encrypt data :type input_file: str :type output_file: str :type crypter_key: str :returns bool """ #Crypter key to bytes crypter_key = crypter_key.encode() try: ihnd = open(input_file, 'rb') #Get file size ihnd.seek(0, 2) filesize = ihnd.tell() ihnd.seek(0, 0) filesize_bytes = bytearray() filesize_bytes.append(filesize & 0xff) filesize_bytes.append((filesize << 8) & 0xff) filesize_bytes.append((filesize << 16) & 0xff) filesize_bytes.append((filesize << 24) & 0xff) digest = hash_md5() digest.update(filesize_bytes) iv = bytearray(digest.digest()) #Iv[15] must be AND with 0xF0 and then OR with filesize & 0x0F iv[15] = (iv[15] & 0xF0) | (filesize & 0x0F) #Write filename at the beginning of file print_info("IV is %s" % hexlify(iv)) #AES key is MD5SUM between IV and crypter key digest = hash_md5() digest.update(iv) digest.update(crypter_key) aes_key = digest.digest() print_info("AES key is %s" % hexlify(aes_key)) #Init AES crypter crypter = AES.new(aes_key, AES.MODE_CBC, bytearray(iv)) #Prepare key_ipad and k_opad, I don't know what they are... key_opad = bytearray() key_ipad = bytearray() for i in range(64): key_ipad.append(0x36) key_opad.append(0x5C) for i in range(16): key_ipad[i] = 0x36 ^ aes_key[i] key_opad[i] = 0x5C ^ aes_key[i] #Prepare the final digest digest = hash_md5() digest.update(key_ipad) #Open file try: ohnd = open(output_file, 'wb') #Write IV ohnd.write(iv) #Read, Encrypt and write index = 0 input_block = bytearray(block_size) progress = 0 while index < filesize: size = block_size if filesize - index < block_size: size = filesize - index for i in range(size): input_block[i] = ord(ihnd.read(1)) input_block = bytearray(crypter.encrypt(bytes(input_block))) # index : filesize = progress : 100 progress = (index * 100) / filesize print_progress_bar(progress, 100) #Write bytes ohnd.write(input_block) #Update digest with encrypted block digest.update(input_block) index += size #Calculate final HMAC final_hmac = digest.digest() digest = hash_md5() digest.update(key_opad) digest.update(final_hmac) final_hmac = digest.digest() print_info("HMAC: %s" % hexlify(final_hmac)) #Write HMAC at the end of the file ohnd.write(final_hmac) print_info("Wrote %d bytes" % (index + 32)) # Write original file size at the end of file data_size_bytes = (filesize).to_bytes(8, byteorder="big") print_info("Wrote 8 bytes at the end %s" % hexlify(data_size_bytes).decode("utf-8")) ohnd.write(data_size_bytes) ohnd.close() except IOError as err: print_err("IOError: %s" % err) return False ihnd.close() except IOError as err: print_err("Could not open input file %s: %s" % (input_file, err)) return False print_info("Encrypted data written to %s" % output_file) return True
def _md5(path): md5_algo = hash_md5() with open(path, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): md5_algo.update(chunk) return md5_algo.hexdigest()