
    ?hM;                         S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	J
r
Jr  SSKJr  SSKJrJr  SSKJr  SSKJr  SSKrSSKrSSKrSS	KJr   " S
 S5      rS rS r\S:X  a  \" 5         gg)a  
Secure Password Vault for Python Applications
Uses industry-standard encryption (AES-256-GCM) with PBKDF2 key derivation

pip install cryptography

# Create a new vault
python vault.py create

# Store a password
python vault.py store gmail john.doe@gmail.com

# Retrieve a password
python vault.py get gmail

# List all services
python vault.py list

# Delete a password
python vault.py delete gmail

# Change master password
python vault.py change-master

    N)Path)DictOptionalAny)
PBKDF2HMAC)hashesserialization)AESGCM)InvalidSignature)datetimec                   H   \ rS rSrSrSS\4S jjrS\S\S\4S	 jrS\S\S\4S
 jr	S\
\\4   S\S\4S jrS\S\S\
\\4   4S jrSS\S\4S jjrSS\S\4S jjrS rSS\S\S\S\S\4
S jjrS\S\\
\\4      4S jrS\4S jrS\S\4S jrSS\S\4S jjrS rSrg) SecureVault,   a_  
Secure password vault using AES-256-GCM encryption with PBKDF2 key derivation.

Security Features:
- AES-256-GCM encryption (authenticated encryption)
- PBKDF2-SHA256 key derivation (600,000 iterations)
- Cryptographically secure random salts and nonces
- Master password verification without storing password
- Secure memory handling where possible
N
vault_pathc                     U(       a  [        U5      O[         R                  " 5       S-  S-  U l        U R                  R                  R	                  SSS9  S U l        g )Nz.secure_vaultz	vault.enci  T)modeexist_ok)r   homer   parentmkdir_master_key)selfr   s     C:\Oracle\vault\vault.py__init__SecureVault.__init__8   sH    .8$z*diikO>[^i>i$$%$$?    passwordsaltreturnc                     [        [        R                  " 5       SUSS9nUR                  UR	                  S5      5      $ )z7Derive encryption key from master password using PBKDF2    '	 )	algorithmlengthr   
iterationsutf-8)r   r   SHA256deriveencode)r   r   r   kdfs       r   _derive_keySecureVault._derive_key=   s8    mmo	
 zz(//'233r   c                 n    [         R                  " SUR                  S5      US5      R                  5       $ )z5Create a hash of the master password for verificationsha256r&   r"   )hashlibpbkdf2_hmacr)   hex)r   r   r   s      r   _create_password_hash!SecureVault._create_password_hashG   s+    ""8X__W-EtVTXXZZr   datamaster_passwordc                    [         R                  " S5      n[         R                  " S5      nU R                  X#5      nU R                  X#5      nS[        R
                  " 5       R                  5       UUS.n[        U5      nUR                  U[        R                  " U5      R                  S5      S5      n	[        R                  " U5      R                  S5      [        R                  " U5      R                  S5      [        R                  " U	5      R                  S5      S.n
[        R                  " U
5      R                  S5      $ )zEncrypt vault datar!      z1.0)versioncreatedpassword_hashentriesr&   N)r   nonce
ciphertext)secretstoken_bytesr+   r2   r   now	isoformatr
   encryptjsondumpsr)   base64	b64encodedecode)r   r4   r5   r   r<   keyr:   
vault_dataaesgcmr=   encrypted_packages              r   _encrypt_dataSecureVault._encrypt_dataK   s    ""2&##B' 5 22?I ||~//1*	

 ^^E4::j+A+H+H+QSWX
 $$T*11':%%e,33G< **:6==gF
 zz+,33G<<r   encrypted_datac                 D    [         R                  " UR                  S5      5      n[        R                  " US   5      n[        R                  " US   5      n[        R                  " US   5      nU R                  X$5      n[        U5      nUR                  XVS5      n	[         R                  " U	R                  S5      5      n
U R                  X$5      nU
S   U:w  a  [        S5      eU
S   $ ! [         R                  [        [        4 a  n[        S	5      UeSnAff = f)
zDecrypt vault datar&   r   r<   r=   Nr:   zInvalid master passwordr;   z(Invalid vault file or incorrect password)rC   loadsrG   rE   	b64decoder+   r
   decryptr2   
ValueErrorJSONDecodeErrorKeyErrorr   )r   rN   r5   packager   r<   r=   rH   rJ   decrypted_datarI   expected_hashes                r   _decrypt_dataSecureVault._decrypt_datal   s	   	Pjj!6!6w!?@G##GFO4D$$WW%56E))',*?@J ""?9C C[F#^^EtDNN$9$9'$BCJ !66MM/*m; !:;;i(($$h0@A 	PGHaO	Ps   C,C/ /DDDc                 :   U R                   R                  5       (       a9  [        SU R                    S35      nUR                  5       S:w  a  [	        S5        gU(       d\   [
        R
                  " S5      n[
        R
                  " S5      nX:w  a  [	        S	5        M?  [        U5      S
:  a  [	        S5        M[   U R                  0 U5      nU R                   R                  U5        U R                   R                  S5        [	        SU R                    35        g)Create a new vaultzVault already exists at z. Overwrite? (y/N): yzVault creation cancelled.FTEnter master password: zConfirm master password: (Passwords don't match. Please try again.r7   4Master password must be at least 12 characters long.i  zVault created successfully at )
r   existsinputlowerprintgetpasslenrL   write_byteschmod)r   r5   responseconfirm_passwordrN   s        r   create_vaultSecureVault.create_vault   s    ??!!##77HH\]^H~~3&12")//2K"L#*??3N#O "6DE'",PQ ++B@ 	##N3e$.t.?@Ar   c                 |   U R                   R                  5       (       d  [        SU R                    35        gU(       d  [        R                  " S5      n U R                   R	                  5       nU R                  X!5      U l        Xl        [        S5        g! [         a  n[        SU 35         SnAgSnAff = f)z%Unlock the vault with master passwordzVault not found at Fr_   zVault unlocked successfully.TzFailed to unlock vault: N)	r   rb   re   rf   
read_bytesrZ   _vault_data_master_passwordrS   )r   r5   rN   rY   s       r   unlock_vaultSecureVault.unlock_vault   s    %%''''89:%oo.GHO	!__779N#11.RD$3!01 	,QC01	s   AB 
B;#B66B;c                     [        U S5      (       a  U R                  (       d  [        S5      eU R                  U R                  U R                  5      nU R
                  R                  U5        g)zSave current vault staterp   zVault is not unlockedN)hasattrrq   RuntimeErrorrL   rp   r   rh   )r   rN   s     r   _save_vaultSecureVault._save_vault   sS    t]++43H3H677++D,<,<d>S>ST##N3r   serviceusernamenotesc                    [        U S5      (       d  [        S5        gUUU[        R                  " 5       R	                  5       [        R                  " 5       R	                  5       S.nXR
                  ;   a%  U R
                  U   R                  SUS   5      US'   XPR
                  U'   U R                  5         [        SU S35        g)	zStore a password in the vaultrp   +Vault is not unlocked. Please unlock first.F)rz   r   r{   r9   modifiedr9   Password for 'z' stored successfully.T)ru   re   r   r@   rA   rp   getrw   )r   ry   rz   r   r{   entrys         r   store_passwordSecureVault.store_password   s    t]++?@ ! ||~//1 002
 &&&#//8<<YiHXYE)$)!wi'=>?r   c                 r    [        U S5      (       d  [        S5        gU R                  R                  U5      $ )z"Retrieve a password from the vaultrp   r}   N)ru   re   rp   r   r   ry   s     r   get_passwordSecureVault.get_password   s2    t]++?@##G,,r   c                     [        U S5      (       d  [        S5        / $ [        U R                  R	                  5       5      $ )zList all services in the vaultrp   r}   )ru   re   listrp   keysr   s    r   list_servicesSecureVault.list_services   s7    t]++?@ID$$))+,,r   c                     [        U S5      (       d  [        S5        gXR                  ;   a-  U R                  U	 U R                  5         [        SU S35        g[        SU S35        g)	z Delete a password from the vaultrp   r}   Fr   z' deleted successfully.Tz	Service 'z' not found in vault.)ru   re   rp   rw   r   s     r   delete_passwordSecureVault.delete_password   sk    t]++?@&&&  )N7)+BCDIgY&;<=r   new_passwordc                 F   [        U S5      (       d  [        S5        gU(       d\   [        R                  " S5      n[        R                  " S5      nX:w  a  [        S5        M?  [        U5      S:  a  [        S	5        M[   Xl        U R                  5         [        S
5        g)zChange the master passwordrp   r}   FTzEnter new master password: zConfirm new master password: r`   r7   ra   z%Master password changed successfully.)ru   re   rf   rg   rq   rw   )r   r   rk   s      r   change_master_password"SecureVault.change_master_password   s    t]++?@&/LM#*??3R#S 3DE|$r)PQ ,56r   c                     [        U S5      (       a  U R                  R                  5         U ?[        U S5      (       a  S[        U R                  5      -  U l        U ?[        S5        g)z3Lock the vault and clear sensitive data from memoryrp   rq   xzVault locked.N)ru   rp   clearrg   rq   re   r   s    r   
lock_vaultSecureVault.lock_vault  s[    4''""$ 4+,,$'#d.C.C*D$DD!%or   )r   rq   rp   r   )N) )__name__
__module____qualname____firstlineno____doc__strr   bytesr+   r2   r   r   rL   rZ   boolrl   rr   rw   r   r   r   r   r   r   r   r   __static_attributes__ r   r   r   r   ,   sD   	 3  
4C 4u 4 4[c [ [3 [=$sCx. =3 =5 =BPE PC PDQTVYQYN P6C 4 BC 4 &4c S C PS ]a ,-C -HT#s(^,D --t -s t 3 $ 4r   r   c                  P   [         R                  " SS9n U R                  SSS9  U R                  SSS9nUR	                  S	S
S9nUR	                  SSS9nUR                  SSS9  UR                  SSS9  UR                  SSSS9  UR	                  SSS9nUR                  SSS9  UR	                  SSS9nUR	                  SSS9nUR                  SSS9  UR	                  SSS9nU R                  5       nUR                  (       d  U R                  5         g[        UR                  5      n	UR                  S	:X  a  U	R                  5         gUR                  S:X  a|  U	R                  5       (       af  [        R                  " SUR                   S35      n
U	R                  UR                  UR                  XR                   5        U	R#                  5         ggUR                  S:X  a  U	R                  5       (       a  U	R%                  UR                  5      nU(       ax  ['        S UR                   35        ['        S!US    35        ['        S"US#    35        US$   (       a  ['        S%US$    35        ['        S&US'    35        ['        S(US)    35        O['        S*UR                   S+35        U	R#                  5         ggUR                  S:X  a  U	R                  5       (       aw  U	R)                  5       nU(       aD  ['        S,5        [+        U5       H)  nU	R%                  U5      n['        S-U S.US    S/35        M+     O['        S05        U	R#                  5         ggUR                  S:X  ao  U	R                  5       (       aY  [-        S1UR                   S235      nUR/                  5       S3:X  a  U	R1                  UR                  5        U	R#                  5         ggUR                  S:X  a7  U	R                  5       (       a!  U	R3                  5         U	R#                  5         ggg)4z-Command-line interface for the password vaultzSecure Password Vault)descriptionz--vault-pathzPath to vault file)helpcommandzAvailable commands)destr   creater]   storezStore a passwordry   zService namerz   Usernamez--notesr   zAdditional notes)defaultr   r   zRetrieve a passwordr   zList all servicesdeletezDelete a passwordzchange-masterzChange master passwordNzEnter password for z: z	Service: z
Username: z
Password: r   r{   zNotes: z	Created: r9   z
Modified: r~   zNo password found for ''zStored services:z  - z ()zNo passwords stored in vault.zDelete password for 'z
'? (y/N): r^   )argparseArgumentParseradd_argumentadd_subparsers
add_parser
parse_argsr   
print_helpr   r   rl   rr   rf   ry   r   rz   r{   r   r   re   r   sortedrc   rd   r   r   )parser
subparserscreate_parserstore_parser
get_parserlist_parserdelete_parserchange_parserargsvaultr   r   servicesry   confirms                  r   mainr   !  s   $$1HIF
-AB&&I<P&QJ ))(9M)NM ((7I(JLin=jz:i:LM &&u3H&IJIN; ''5H'IK ))(9L)MMy~> ))/@X)YMD<<(E||x		 )<T\\N"'MNH  t}}h

S  
 
	&&t||4E	$,,01
5#4"567
5#4"567>GE'N#345	%	"2!345
5#4"567/~Q?@   
	**,H()%h/G!..w7ED	E*,=+>a@A  0 56   
	!3DLL>LMG}}#%%%dll3	   
	(((*   
)r   c                  d   [        S5      n U R                  R                  5       (       d  U R                  S5        U R	                  S5      (       a_  U R                  SSSS5        U R                  S5      nU(       a"  [        SUS    35        [        S	US
    35        U R                  5         gg)z;Example of how to use the vault in your Python applicationszmy_app_vault.encyour_secure_master_passworddatabaseadminsuper_secret_passwordzProduction DBzDB Username: rz   zDB Password: r   N)	r   r   rb   rl   rr   r   r   re   r   )r   db_credss     r   example_library_usager   y  s     *+E ""$$89 788 	Z2I?[ %%j1M(:"6!789M(:"6!789 	 9r   __main__)r   osrC   rE   rf   r/   pathlibr   typingr   r   r   )cryptography.hazmat.primitives.kdf.pbkdf2r   cryptography.hazmat.primitivesr   r	   +cryptography.hazmat.primitives.ciphers.aeadr
   cryptography.exceptionsr   r>   r   sysr   r   r   r   r   r   r   r   <module>r      si   4 
      & & @ @ > 4   
 r rjTp4 zF r   