File size: 7,403 Bytes
e44d75a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# Initialize session state variables if they don't exist
if 'failed_attempts' not in st.session_state:
st.session_state.failed_attempts = 0
if 'stored_data' not in st.session_state:
st.session_state.stored_data = {}
if 'current_page' not in st.session_state:
st.session_state.current_page = "Home"
if 'last_attempt_time' not in st.session_state:
st.session_state.last_attempt_time = 0
# Function to hash passkey
def hash_passkey(passkey):
return hashlib.sha256(passkey.encode()).hexdigest()
# Function to generate a key from passkey (for encryption)
def generate_key_from_passkey(passkey):
# Use the passkey to create a consistent key
hashed = hashlib.sha256(passkey.encode()).digest()
# Ensure it's valid for Fernet (32 url-safe base64-encoded bytes)
return base64.urlsafe_b64encode(hashed[:32])
# Function to encrypt data
def encrypt_data(text, passkey):
key = generate_key_from_passkey(passkey)
cipher = Fernet(key)
return cipher.encrypt(text.encode()).decode()
# Function to decrypt data
def decrypt_data(encrypted_text, passkey, data_id):
try:
# Check if the passkey matches
hashed_passkey = hash_passkey(passkey)
if data_id in st.session_state.stored_data and st.session_state.stored_data[data_id]["passkey"] == hashed_passkey:
# If passkey matches, decrypt the data
key = generate_key_from_passkey(passkey)
cipher = Fernet(key)
decrypted = cipher.decrypt(encrypted_text.encode()).decode()
st.session_state.failed_attempts = 0
return decrypted
else:
# Increment failed attempts
st.session_state.failed_attempts += 1
st.session_state.last_attempt_time = time.time()
return None
except Exception as e:
# If decryption fails, increment failed attempts
st.session_state.failed_attempts += 1
st.session_state.last_attempt_time = time.time()
return None
# Function to generate a unique ID for data
def generate_data_id():
import uuid
return str(uuid.uuid4())
# Function to reset failed attempts
def reset_failed_attempts():
st.session_state.failed_attempts = 0
# Function to change page
def change_page(page):
st.session_state.current_page = page
# Streamlit UI
st.title("π Secure Data Encryption System")
# Navigation
menu = ["Home", "Store Data", "Retrieve Data", "Login"]
choice = st.sidebar.selectbox("Navigation", menu, index=menu.index(st.session_state.current_page))
# Update current page based on selection
st.session_state.current_page = choice
# Check if too many failed attempts
if st.session_state.failed_attempts >= 3:
# Force redirect to login page
st.session_state.current_page = "Login"
st.warning("π Too many failed attempts! Reauthorization required.")
# Display current page
if st.session_state.current_page == "Home":
st.subheader("π Welcome to the Secure Data System")
st.write("Use this app to **securely store and retrieve data** using unique passkeys.")
col1, col2 = st.columns(2)
with col1:
if st.button("Store New Data", use_container_width=True):
change_page("Store Data")
with col2:
if st.button("Retrieve Data", use_container_width=True):
change_page("Retrieve Data")
# Display stored data count
st.info(f"Currently storing {len(st.session_state.stored_data)} encrypted data entries.")
elif st.session_state.current_page == "Store Data":
st.subheader("π Store Data Securely")
user_data = st.text_area("Enter Data:")
passkey = st.text_input("Enter Passkey:", type="password")
confirm_passkey = st.text_input("Confirm Passkey:", type="password")
if st.button("Encrypt & Save"):
if user_data and passkey and confirm_passkey:
if passkey != confirm_passkey:
st.error("β οΈ Passkeys do not match!")
else:
# Generate a unique ID for this data
data_id = generate_data_id()
# Hash the passkey
hashed_passkey = hash_passkey(passkey)
# Encrypt the data
encrypted_text = encrypt_data(user_data, passkey)
# Store in the required format
st.session_state.stored_data[data_id] = {
"encrypted_text": encrypted_text,
"passkey": hashed_passkey
}
st.success("β
Data stored securely!")
# Display the data ID for retrieval
st.code(data_id, language="text")
st.info("β οΈ Save this Data ID! You'll need it to retrieve your data.")
else:
st.error("β οΈ All fields are required!")
elif st.session_state.current_page == "Retrieve Data":
st.subheader("π Retrieve Your Data")
# Show attempts remaining
attempts_remaining = 3 - st.session_state.failed_attempts
st.info(f"Attempts remaining: {attempts_remaining}")
data_id = st.text_input("Enter Data ID:")
passkey = st.text_input("Enter Passkey:", type="password")
if st.button("Decrypt"):
if data_id and passkey:
if data_id in st.session_state.stored_data:
encrypted_text = st.session_state.stored_data[data_id]["encrypted_text"]
decrypted_text = decrypt_data(encrypted_text, passkey, data_id)
if decrypted_text:
st.success("β
Decryption successful!")
st.markdown("### Your Decrypted Data:")
st.code(decrypted_text, language="text")
else:
st.error(f"β Incorrect passkey! Attempts remaining: {3 - st.session_state.failed_attempts}")
else:
st.error("β Data ID not found!")
# Check if too many failed attempts after this attempt
if st.session_state.failed_attempts >= 3:
st.warning("π Too many failed attempts! Redirecting to Login Page.")
st.session_state.current_page = "Login"
st.rerun() # Updated from experimental_rerun()
else:
st.error("β οΈ Both fields are required!")
elif st.session_state.current_page == "Login":
st.subheader("π Reauthorization Required")
# Add a simple timeout mechanism
if time.time() - st.session_state.last_attempt_time < 10 and st.session_state.failed_attempts >= 3:
remaining_time = int(10 - (time.time() - st.session_state.last_attempt_time))
st.warning(f"π Please wait {remaining_time} seconds before trying again.")
else:
login_pass = st.text_input("Enter Master Password:", type="password")
if st.button("Login"):
if login_pass == "admin123": # Hardcoded for demo, replace with proper auth
reset_failed_attempts()
st.success("β
Reauthorized successfully!")
st.session_state.current_page = "Home"
st.rerun() # Updated from experimental_rerun()
else:
st.error("β Incorrect password!")
# Add a footer
st.markdown("---")
st.markdown("π Secure Data Encryption System | Educational Project") |