How to protect data written in my application like a password - security

I made a trade program and in it is possible to send emails unfortunately my password and email address are written in the code how can I do to guarantee myself some protection
thank you

Keystore and Keychain are the mobile secure keys (hardware encryption) and has a library for Flutter:
https://pub.dev/packages/flutter_secure_storage
Implementation:
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// Create storage
final storage = new FlutterSecureStorage();
// Read value
String value = await storage.read(key: key);
// Read all values
Map<String, String> allValues = await storage.readAll();
// Delete value
await storage.delete(key: key);
// Delete all
await storage.deleteAll();
// Write value
await storage.write(key: key, value: value);

Related

Implementing JWE encryption for a JWS signed token in Node.JS with Jose 4.11

I have difficulty manipulating the Jose Node.JS documentation to chain the creation of a JWS and JWE. I cannot find the proper constructor for encryption. It looks like I can only encrypt a basic payload not a signed JWS.
Here is the code sample I try to fix to get something that would look like
const jws = await createJWS("myUserId");
const jwe = await encryptAsJWE(jws);
with the following methods
export const createJWS = async (userId) => {
const payload = {
}
payload['urn:userId'] = userId
// importing key from base64 encrypted secret key for signing...
const secretPkcs8Base64 = process.env.SMART_PRIVATE_KEY
const key = new NodeRSA()
key.importKey(Buffer.from(secretPkcs8Base64, 'base64'), 'pkcs8-private-der')
const privateKey = key.exportKey('pkcs8')
const ecPrivateKey = await jose.importPKCS8(privateKey, 'ES256')
const assertion = await new jose.SignJWT(payload)
.setProtectedHeader({ alg: 'RS256' })
.setIssuer('demolive')
.setExpirationTime('5m')
.sign(ecPrivateKey)
return assertion
}
export const encryptAsJWE = async (jws) => {
// importing key similar to createJWS key import
const idzPublicKey = process.env.IDZ_PUBLIC_KEY //my public key for encryption
...
const pkcs8PublicKey = await jose.importSPKI(..., 'ES256')
// how to pass a signed JWS as parameter?
const jwe = await new jose.CompactEncrypt(jws)
.encrypt(pkcs8PublicKey)
return jwe
}
The input to the CompactEncrypt constructor needs to be a Uint8Array, so just wrapping the jws like so (new TextEncoder().encode(jws)) will allow you to move forward.
Moving forward then:
You are also missing the JWE protected header, given you likely use an EC key (based on the rest of your code) you should a) choose an appropriate EC-based JWE Key Management Algorithm (e.g. ECDH-ES) and put that as the public key import algorithm, then proceed to call .setProtectedHeader({ alg: 'ECDH-ES', enc: 'A128CBC-HS256' }) on the constructed object before calling encrypt.
Here's a full working example https://github.com/panva/jose/issues/112#issue-746919790 using a different combination of algorithms but it out to help you get the gist of it.

Azure "JsonWebTokenError: invalid algorithm"

Azure Static Web App (SWA) with integrated API. One of the step at backend API is to validate the Bearer Token with public key submitted in request headers:
const jwt = require("jsonwebtoken"); // v 8.5.1
async function getMSPublicKey(misc) // misc contains kid and tenantId, confirmed in F12 request header
{
var vurl = "https://login.microsoftonline.com/" + misc.tenantId + "/v2.0/.well-known/openid-configuration";
const x1 = await fetch(vurl);
const x2 = await x1.json();
const x3 = await fetch(x2.jwks_uri);
const k = await x3.json();
return pkey = k.keys.find( k => k.kid === misc.kid).x5c[0]; // public key in the entry matching kid
}
var vmisc = JSON.parse(ac.req.headers["misc"]);
var publickey = "-----BEGIN CERTIFICATE-----\n" + await getMSPublicKey(vmisc) + "\n-----END CERTIFICATE-----";
// next line is reported in AppTraces, Message = JsonWebTokenError: invalid algorithm
var payload = jwt.verify(theToken, publickey, { algorithms: ['RS256'] });
// theToken is validated ok at jwt.io
It only occurs when deployed to Azure cloud, local Azure Static Web Apps emulator is all ok.
Update, Guess this is something about Azure cloud, particularly security. similar result on another package Jose, error only on Azure cloud.
Update: found culprit My original code was sending the token in under Authorization name. Azure log shows its read-in length is always 372 vs. 1239 tested in local emulator. After renaming it to something else like mytoken, all good! This is undocumented, reminder to everyone: avoid sensitive/reserved words.
This ought to be painless and work the same with less code on your end, it handles rotation, re-fetching of the public keys, as well as implements a complete applicable JWK selection algorithm for all known JWS algorithms. Also does not depend on a brittle x5c[0] JWK parameter.
const jose = require('jose')
const JWKS = jose.createRemoteJWKSet(new URL(`https://login.microsoftonline.com/${misc.tenantId}/discovery/v2.0/keys`))
// JWKS you keep around for subsequent verifications.
const { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS)
Please check if the below steps help to work around:
Replace the CERTIFICATE keyword with PUBLIC KEY if you're using the public key or PRIVATE KEY if you're using the Private Key or RSA PRIVATE KEY if you are using RSA Private Key.
Also, the problem again occurs in the way we format the Public Key which requires begin and end lines, and line breaks at every 64 characters.
Refer here for more information.

PDFNet Digital Signature in Node JS using Google KMS

I've seen example of signing https://www.pdftron.com/documentation/nodejs/guides/features/signature/sign-pdf
signOnNextSave uses PKCS #12 certificate, but I use Google KMS for asymmetric signing to keep private keys safe.
Here is example of signing and verifying by Google Cloud KMS
I tried to implement custom SignatureHandler but Node.JS API is different from Java or .NET
https://www.pdftron.com/api/pdfnet-node/PDFNet.SignatureHandler.html
How can I implement custom signing and verifying logic?
const data = Buffer.from('pdf data')
// We have 2048 Bit RSA - PSS Padding - SHA256 Digest key in Google Cloud KMS
const signAsymmetric = async () => {
const hash = crypto.createHash('sha256')
hash.update(data)
const digest = hash.digest()
const digestCrc32c = crc32c.calculate(digest)
// Sign the data with Cloud KMS
const [signResponse] = await client.asymmetricSign({
name: locationName,
digest: {
sha256: digest
},
digestCrc32c: {
value: digestCrc32c
}
})
if (signResponse.name !== locationName) {
throw new Error('AsymmetricSign: request corrupted in-transit')
}
if (!signResponse.verifiedDigestCrc32c) {
throw new Error('AsymmetricSign: request corrupted in-transit')
}
if (
crc32c.calculate(signResponse.signature) !==
Number(signResponse.signatureCrc32c.value)
) {
throw new Error('AsymmetricSign: response corrupted in-transit')
}
// Returns signature which is buffer
const encoded = signResponse.signature.toString('base64')
console.log(`Signature: ${encoded}`)
return signResponse.signature
}
// Verify data with public key
const verifyAsymmetricSignatureRsa = async () => {
const signatureBuffer = await signAsymmetric()
const publicKeyPem = await getPublicKey()
const verify = crypto.createVerify('sha256')
verify.update(data)
verify.end()
const key = {
key: publicKeyPem,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING
}
// Verify the signature using the public key
const verified = verify.verify(key, signatureBuffer)
return verified
}
At this time, the PDFTron SDK only supports custom handlers on C++, Java, and C# (there are more plans to include additional languages in the future).
On a different platform like C++, you would extend the custom handler functions by putting hash.update(data) into SignatureHandler::AppendData, and the rest of signAsymmetric would go into SignatureHandler::CreateSignature. A name would be given to the custom handler for interoperability like Adobe.PPKLite (we do not yet support custom handler SubFilter entries, only Filter -- see PDF standard for the difference -- but this won't matter so long as you use a verification tool that supports Filter Adobe.PPKLite). Please see the following link for a concrete example:
https://www.pdftron.com/documentation/samples/cpp/DigitalSignaturesTest
As for verification, our code can already do this for you if your signatures fulfill the following conditions:
they use a standard digest algorithm
they use RSA to sign
they use the correct data formats according to the PDF standard (i.e. detached CMS, digital signature dictionary)
If you have more questions or require more details, please feel free to reach out to PDFTron support at support#pdftron.com

How keep in the secret the RSA - private key in browser - implement Proof of Possession with an Asymmetric Key

I want to implement the Proof of Possession with an Asymmetric Key specs.
I would like to store the RSA in secure place in the browser - I will be able to sign the part of the request with private key and with public key as part of JWT verify the request.
I don't know how import RSA into my browser - where can I store RSA private key secure in browser?
Look at the WebCrypto API and IndexedDB. There are some WebCrypto examples here - https://github.com/diafygi/webcrypto-examples.
This will allow you to import the key in a way that it cannot be extracted - only used to sign and verify signatures. This will however be wiped when browser data is cleared with the "clear application data" (/similar - depends on browser) flag is ticked.
For example to import a key and store it in an IndexedDB (this code hasn't been tested / _openDb would have to be implemented) -
window.crypto.subtle.importKey(
"jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
{ //this is an example jwk key, other key types are Uint8Array objects
kty: "RSA",
e: "AQAB",
n: "vGO3eU16ag9zRkJ4AK8ZUZrjbtp5xWK0LyFMNT8933evJoHeczexMUzSiXaLrEFSyQZortk81zJH3y41MBO_UFDO_X0crAquNrkjZDrf9Scc5-MdxlWU2Jl7Gc4Z18AC9aNibWVmXhgvHYkEoFdLCFG-2Sq-qIyW4KFkjan05IE",
alg: "PS256",
ext: true,
},
{ //these are the algorithm options
name: "RSA-PSS",
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
false, //whether the key is extractable (i.e. can be used in exportKey)
["verify"] //"verify" for public key import, "sign" for private key imports
).then(function(key){
((_db_handle === null) ?
_openDb() :
Promise.resolve()
).then(function() {
let tx = _db_handle.transaction("KeyStore", "readwrite");
let store = tx.objectStore("KeyStore");
let putKey = store.put({id: "Key 1", key: key});
putKey.onsuccess = function() {
resolve();
};
putKey.onerror = function() {
reject(putKey.error);
};
});
})
Then to read it back out -
let tx = _db_handle.transaction("KeyStore", "readwrite");
let store = tx.objectStore("KeyStore");
let getKey = store.get("Key 1");
getKey.onsuccess = function() {
resolve(getKey.result ? getKey.result.key : null);
};
getKey.onerror = function() {
reject(getKey.error);
};
Maybe you can create an extension for holding keys. Consider that if you need to store private keys in a browser, you should only allow to store encrypted keys per default and in addition if you want/need to store more keys don't allow the same password on different key files.
Also consider using a master key and/or OTPs to decrypt the store.
Looking for an extension where these things are available could save some work

ASP.Net Identity 2 Reset password with SMS

I'm looking to send the user an SMS when reseting their password. I already have the facilities to send a SMS, I just need a guide on how to set it up with Identity 2.0. I can't seem to find any useful info online, the reference code itself isn't properly commented either.
I want to generate a security code, send it to the user, he must then input it into a form and then be allowed to reset his/her password. Can anyone direct me to a guide/tutorial that explains this process?
After digging in the identity source code i found an alternative token provider that can generate tokens similar to phone number confirmation (six digits).
I had to implement two methods in my UserManager to generate the code and then to validate it.
I declared the token provider inside the UserManager
private TotpSecurityStampBasedTokenProvider<User, string> smsResetTokenProvider = new TotpSecurityStampBasedTokenProvider<User, string>();
This is the first method to generate the code:
public async Task<string> GenerateSMSPasswordResetToken(string userId)
{
var user = await base.FindByIdAsync(userId);
var token = await smsResetTokenProvider.GenerateAsync("Reset Password", this, user);
return token;
}
This is the second method to validate the code:
public async Task<IdentityResult> SMSPasswordResetAsync(string userId, string token, string newPassword)
{
var user = await base.FindByIdAsync(userId);
var valid = await smsResetTokenProvider.ValidateAsync("Reset Password", token, this, user);
if (valid)
{
var passwordStore = Store as IUserPasswordStore<User, string>;
var result = await UpdatePassword(passwordStore, user, newPassword);
if (!result.Succeeded)
{
return result;
}
return await UpdateAsync(user);
}
else
{
return IdentityResult.Failed("InvalidToken");
}
}
You may need to tweak the code depending on your user manager

Resources