Python keyring directly showing password without prompting master password - python-keyring

import keyring
keyring.set_password('test_db','louis','secret123')
keyring.get_password('test_db','louis')
'secret123'

What you need is keyring.cryptfile.
With this way, a cryptfile_pass.cfg file will created with hashed passwords (argon2 hash).
You can use it like this:
from keyrings.cryptfile.cryptfile import CryptFileKeyring
kr = CryptFileKeyring()
kr.set_password("service", "username", "my_secret_key_code")
>>>Type your password: MyPass_word
kr.get_password("service", "username")
>>>Please enter password for encrypted keyring:
if you press:'my_secret_key_code' you will get:
MyPass_word
See more here.

Related

How to generate SAS token using python legacy SDK(2.1) without account_key or connection_string

I am using python3.6 and azure-storage-blob(version = 1.5.0) and trying to use user assigned managed identity to connect to my azure storage blob from an Azure VM.The problem I am facing is I want to generate the SAS token to form a downloadable url.
I am using blob_service = BlockBlobService(account name,token credential) to authenticate. But I am not able to find any methods which let me generate SAS token without supplying the account key.
Also not seeing any way of using the user delegation key as is available in the new azure-storage-blob (versions>=12.0.0). Is there any workaround or I will need to upgrade the azure storage library at the end.
I tried to reproduce in my environment to generate SAS token without account key or connection string got result successfully.
Code:
import datetime as dt
import json
import os
from azure.identity import DefaultAzureCredential
from azure.storage.blob import (
BlobClient,
BlobSasPermissions,
BlobServiceClient,
generate_blob_sas,
)
credential = DefaultAzureCredential(exclude_shared_token_cache_credential=True)
storage_acct_name = "Accountname"
container_name = "containername"
blob_name = "Filename"
url = f"https://<Accountname>.blob.core.windows.net"
blob_service_client = BlobServiceClient(url, credential=credential)
udk = blob_service_client.get_user_delegation_key(
key_start_time=dt.datetime.utcnow() - dt.timedelta(hours=1),
key_expiry_time=dt.datetime.utcnow() + dt.timedelta(hours=1))
sas = generate_blob_sas(
account_name=storage_acct_name,
container_name=container_name,
blob_name=blob_name,
user_delegation_key=udk,
permission=BlobSasPermissions(read=True),
start = dt.datetime.utcnow() - dt.timedelta(minutes=15),
expiry = dt.datetime.utcnow() + dt.timedelta(hours=2),
)
sas_url = (
f'https://{storage_acct_name}.blob.core.windows.net/'
f'{container_name}/{blob_name}?{sas}'
)
print(sas_url)
Output:
Make sure you need to add storage blob data contributor role as below:

Hide password in Genexus beforeConnect procedure

I'm using the BeforeConnect option in Genexus. I put this code in a procedure...
&UserID = &websession.Get("db")
//select the Database depending on websession
Do Case
Case &UserID = "1"
&DataBase = "CambioDB1"
Case &UserID = "2"
&DataBase = "CambioDB2"
Otherwise
&DataBase = "CambioDB1" //default database
EndCase
//Change connection properties
&dbconn = GetDatastore("Default")
&dbconn.UserName = 'username'
&dbconn.UserPassword = 'password'
&dbconn.ConnectionData = "DATABASE=" + &DataBase.Trim() //SQLServer
... set the BeforeConnect property and it works.
But how can I avoid to put the password of the db in the code?
I was thinking to use a file to read from, but it would be an unencrypted password anyway.
How can I solve this? Is there a way to manage this or do I have to risk the password in clear text?
Nicola,
You may use the ConfigurationManager to read a value from the standard config file (client.cfg for Java, web.config for .net).
&MyPassword = ConfigurationManager.GetValue('MY_PASSWORD')
Add a value to your configuration file with the password.
For example:
MY_PASSWORD=my-db-password
You probably want to save the password encrypted for an extra layer of security.
Simple:
&EncPass = Encrypt64(&Password, &SysEncKey)
Stonger encryption:
https://wiki.genexus.com/commwiki/servlet/wiki?42682,Symmetric+Stream+Encryption
&EncPass = &SymmetricStreamCipher.DoEncrypt(symmetricStreamAlgorithm, key, iv, plainText)

Transferring a zip to ec2 via local ssh key

Using below code to zip a directory (works) and transfer it to the ec2 host using ssh.
data "archive_file" "scripts" {
type = "zip"
source_dir = "${path.module}/files/app"
output_path = "${path.module}/files/app.zip"
}
resource "null_resource" "upload" {
provisioner "file" {
source = data.archive_file.scripts.output_path
destination = "/home/${var.ec2_user}/${data.archive_file.scripts.output_path}"
connection {
type = "ssh"
user = var.ec2_user
private_key = file("C:/Users/myuser/.ssh/id_rsa.ppk")
host = var.hostname
}
}
}
However I get the following error:
Error: Failed to read ssh private key: no key found
How do I use a local ssh key to transfer the zip to the remote host?
The files are small, should I be using provisioner?
Thanks
Error: Failed to read ssh private key: no key found
That error means that no private key was found in the file specified.
In the following line of your example, you are specifying a private key in Putty format.
private_key = file("C:/Users/myuser/.ssh/id_rsa.ppk")
Terraform expects private keys to be RSA or ECDSA PEM files. Your SSH server might only support RSA. Newer SSH servers usually support both RSA and ECDSA.
If you created your private key with OpenSSL, then the private key filename defaults to id_rsa. If that file exists, change your Terraform to:
private_key = file("C:/Users/myuser/.ssh/id_rsa")

How to sign JWT?

I'm trying to secure a Sinatra API.
I'm using ruby-jwt to create the JWT, but I don't know exactly what to sign it with.
I'm trying to use the user's BCrypt password_digest, but every time password_digest is called it changes, making the signature invalid when I go to verify it.
Use any kind of application secret key, not a user's bcrypt password digest.
For example, use the dot env gem and a .env file, with an entry such as:
JWT_KEY=YOURSIGNINGKEYGOESHERE
I personally generate a key by using a simple random hex string:
SecureRandom.hex(64)
The hex string contains just 0-9 and a-f, so the string is URL safe.
For RS256 public and private key strategy you can use Ruby OpenSSL lib:
Generating keys:
key = OpenSSL::PKey::RSA.new 2048
open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
Load key from .pem file to sign token:
priv_key = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
token = JWT.encode payload, priv_key, 'RS256'
Load key from .pem file to Verify token(Create a middleware for this):
begin
# env.fetch gets http header
bearer = env.fetch('HTTP_AUTHORIZATION').slice(7..-1)
pub_key = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
payload = JWT.decode bearer, pub_key, true, { algorithm: 'RS256'}
# access your payload here
#app.call env
rescue JWT::ExpiredSignature
[403, { 'Content-Type' => 'text/plain' }, ['The token has expired.']]
rescue JWT::DecodeError
[401, { 'Content-Type' => 'text/plain' }, ['A token must be passed.']]
rescue JWT::InvalidIssuerError
[403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid issuer.']]
rescue JWT::InvalidIatError
[403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid "issued at" time.']]
end
To use RSA key in your .env instead of loading a file, you will need to use gem 'dotenv' and import the key as a single line variable with the use of newline '\n'. check this question on how to do it. example:
PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nmineminemineminemine\nmineminemineminemine\nmineminemine...\n-----END PUBLIC KEY-----\n"
as an .env PUBLIC_KEY variable, loading the key will change to this:
key = OpenSSL::PKey::RSA.new ENV['PUBLIC_KEY']
According to wikipedia, a secret key used in cryptography is basically just that, a key to open the lock. The key should be consistent and reliable, but not easy to duplicate, just like a key you would use on your home.
As stated in this answer, secret keys should be randomly-generated. However, you still want the key to be retained for use across the application. By using the password digest from bcrypt, you are actually using a hashed key that was derived from a base secret key (the password). Because the hash is random, this is not a reliable secret key to use, as you stated.
The previous answer using SecureRandom.hex(64) is a great way to create an initial base application key. However, in a production system, you should be taking this in as a configuration variable and storing it for consistent use across multiple runs of your application (for example following a server reboot, you should not invalidate all of your user's JWTs) or across multiple distributed servers. This article gives an example of pulling in the secret key from an environment variable for rails.

WebSphere wsadmin jython - prompting for password

I am looking for a way to prompt for password (that is, no input echo).
I am using jython in WebSphere's 7.0.0.19 wsadmin.
I've looked for it - it appears to be possible with import getpass or import termios (but I get "no module named ..." exception).
Any way to prompt for password anyway?
Thank you.
You can use the following code. It basically uses Java's console() if present (note that console may not be present all the time) else use raw_input() and password masking logic.
# if console is not available (ex: when invoked from a shell script or another java process)
# we need to fall back to use raw_input, but we should mask the password if we use it
import sys, thread, time, threading
from java.lang import String
def getPass(stream=None):
console = java.lang.System.console()
if console is None:
global p_stopMasking
if not stream:
stream = sys.stderr
try:
p_stopMasking = 0
threading.Thread(target=_doMasking,args=(stream,)).start()
password = raw_input()
p_stopMasking = 1
except Exception, e:
p_stopMasking = 1
print "Error Occured"
print e
exit()
else:
password = console.readPassword()
return String.valueOf(password)
def _doMasking(stream):
while not p_stopMasking:
stream.write("\010*")
#stream.write("\n")
stream.flush()
time.sleep(0.01)
def populateCredentials():
global username
global password
print 'Enter username:'
username = raw_input();
print 'Enter password:'
password = getPass(sys.stdout);
# start main
print 'start program...'
p_stopMasking= 1
username = None
password = None
populateCredentials()
print 'username is : ' + username
print 'password is : ' + password
The following also worked for me:
raw_input("")
myPass = raw_input("Please enter a password: ")
This isn't perfect because it doesn't mask the password, but it does work. For some reason, if you don't specify the first "raw_input" invocation then the script won't block on the second one.

Resources