Generating ASC files with Bouncy Castle C# - bouncycastle

I have this piece of code where its been generated a public and private key using Bouncy Castle API:
RsaKeyPairGenerator g = new RsaKeyPairGenerator();
g.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
AsymmetricCipherKeyPair keyPair = g.GenerateKeyPair();
RsaKeyParameters privateKey = (RsaKeyParameters)keyPair.Private;
RsaKeyParameters publicKey = (RsaKeyParameters)keyPair.Public;
I need to export my keys for an ASC file, for example:
PublicKey.asc
PrivateKey.asc
At the moment, I'm using the code below to create the ASC files:
TextWriter tw = new StringWriter();
PemWriter pw = new PemWriter(tw);
pw.WriteObject(publicKey);
pw.Writer.Flush();
string printPublicKey = tw.ToString();
Console.WriteLine(printPublicKey);
byte[] pbkasc = Encoding.ASCII.GetBytes(printPublicKey);
File.WriteAllBytes("c:\\temp\\PublicKey.asc", pbkasc);
pw.WriteObject(privateKey);
pw.Writer.Flush();
string printPrivateKey = tw.ToString();
Console.WriteLine(printPrivateKey);
byte[] pvkasc = Encoding.ASCII.GetBytes(printPrivateKey);
File.WriteAllBytes("c:\\temp\\PublicKey.asc", pvkasc);
But when I try to import them, to a third party software, Kleopatra for example, I'm receiving the error below:
I'm beginner with all this encryption stuff. So, I need to know if I'm doing that in the correct way or if there is any other to generate those asc files. I did some research and I find this certificate generator:
//// Create PFX (PKCS #12) with private key
//File.WriteAllBytes("c:\\temp\\capronizera.pfx", cert.Export(X509ContentType.Pfx, "senha"));
//// Create Base 64 encoded CER (public key only)
//File.WriteAllText("c:\\temp\\mycert.cer",
// "-----BEGIN CERTIFICATE-----\r\n"
// + Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks)
// + "\r\n-----END CERTIFICATE-----");
But unfortunately, it doesn't apply for my issue/question/doubt.
Thanks. :-)

Related

Performing ECIES operation using Bouncy castle with KeyPair in JKS

I have requirement to perform ECIES encryt/decrypt using secp256r1 with BC as provider.
I have need reference of (1) how to store ECIES private-public key pair in JKS Keystore (2) retrieve public key from JKS.
I have provision key-pair using keytool command as per https://zombiesecured.com/html/tutorials/Keytool/ECC-JK.html.
Signature algorithm name: SHA256withECDSA
Subject Public Key Algorithm: 256-bit EC key
(2) Can you help how to retrieve key in ECDSAPublicKey format as input to encryption .
I have found reference of decoding key to ECPublicKey as below. What should be my 1st argument? How to retrieve encoded key from JKS?
public static ECPublicKey decodePublicKey(byte[] encoded, String namedCurve) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException, IOException
{
KeyFactory fact = KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec(namedCurve);
java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(params.getCurve(), params.getSeed());
java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(ECPointUtil.decodePoint(ellipticCurve,encoded),EC5Util.convertSpec(ellipticCurve, params));
return (ECPublicKey) fact.generatePublic(keySpec);
}
how to use IESCipher, IESParameterSpec, engineInit to perform ECIES encrypt/decrypt.

SQL Server Column Encryption using Azure Key Vault and Spring Boot

I need to save the data in SQL server having column encryption using the Azure Key vault
#Bean
#Primary
public DataSource dataSource() throws SQLException {
KeyVaultClient client = new KeyVaultClient(keyVaultCredentialService);
String userName = client.getSecret(vaultURL, "spring-datasource-username").value();
String password = client.getSecret(vaultURL, "spring-datasource-password").value();
String url = "jdbc:sqlserver://test.database.windows.net;databaseName=encryption_demo;columnEncryptionSetting=Enabled;";
String driverClass = client.getSecret(vaultURL, "spring-datasource-driverClassName").value();
DataSource dataSource = DataSourceBuilder
.create()
.username(userName)
.password(password)
.url(url)
.driverClassName(driverClass)
.build();
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(clientId, clientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider); SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
return dataSource;
}
application.properties
azure.keyvault.uri= ....
azure.keyvault.client-id= ...
azure.keyvault.client-key= ...
SQLServer table
CREATE TABLE [dbo].[Patients](
[id] [int] PRIMARY KEY NOT NULL,
[ssn] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[first_name] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL,
[last_name] [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL
)
GO
While saving the data in DB getting the error:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Internal error while encryption: Illegal key size
Download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Be sure to read the Readme included in the zip file for installation instructions and relevant details on possible export/import issues.
If using the mssql-jdbc-X.X.X.jre7.jar or sqljdbc41.jar, the policy files can be downloaded from Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download.
If using the mssql-jdbc-X.X.X.jre8.jar or sqljdbc42.jar, the policy files can be downloaded from Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download.
If using the mssql-jdbc-X.X.X.jre9.jar, no policy file needs to be downloaded. The jurisdiction policy in Java 9 defaults to unlimited strength encryption.
For more details, you could refer to this article.

Validate an Azure idToken in Node.js

I am having trouble validating the token signature of an Azure idtoken issued by the v2 endpoint.
I have read the documentation (https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-id-and-access-tokens#validating-tokens), and there is also some sample code, but this refers to a languaage other than TS/JS.
Currently I my code is
import {
decode,
verify
} from 'jsonwebtoken';
const token = 'myRand0mIdtoken...meh';
const key = 'key from -->'; // https://login.microsoftonline.com/common/discovery/v2.0/keys
console.log(
decode(token), //works fine!
verify(token, key) //JsonWebTokenError: invalid algorithm
);
How would I go about this? Decoding works, but verifying does not.
The site https://login.microsoftonline.com/common/discovery/v2.0/keys points to a JSON document containing a "keys" array. This contains multiple key objects. Of this, i have used the element in which the "kid" value matches the "kid" value in my idToken's header.
In this element there are two fields, x5t and x5c, which look like public keys. I have tried both, but no luck.
Kind regards
Found the solution.
https://nicksnettravels.builttoroam.com/post/2017/01/24/Verifying-Azure-Active-Directory-JWT-Tokens.aspx
It seems, that I have just forgotten the starting and ending lines encompassing the public key. The working format is:
-----BEGIN CERTIFICATE-----
CONTENT OF x5c FIELD IN THE JSON DOC
-----END CERTIFICATE-----

List of keys that should most probably be removed from log files?

Recently I noticed some sensitive data was being written out to a log file in an app I'm working on. I looked into it, and our app has a list of keys that it will remove from our logs before writing them out, but the list feels to me like it could be expanded.
Is there a list somewhere of common keys that should be removed from log files when found?
For example the following keys and their variations should probably never be logged anywhere in a log file
access_token
auth_token
client_id
client_secret
oauthSecret
oauthToken
password
refresh_token
connection_string
Note that I've seen the OWASP Logging cheat sheet, but it didn't seem to have any specifics in it, just generalizations.
So far the best I've been able to come up with is the following, and I found my best results by searching for "redact secret password token" in Google.
Redact keys that have the following anywhere in their name
remembering that keys can show up in any of the following ways: x=y, x:y, 'x':y, "x":y <x>y</x>
token
secret
password
session
connection
jwt
consider removing all username variations as well, like:
username
user_name
user
email
credential
Redact values that look like
credit card numbers
social insurance numbers
possibly email addresses
Cloudera has a page detailing regular expressions for redacting some data values, not keys:
Credit Card numbers (with separator)
\d{4}[^\w]\d{4}[^\w]\d{4}[^\w]\d{4}
Social Security numbers (with separator) \d{3}[^\w]\d{2}[^\w]\d{4}
Email addresses \b([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-._] \
[A-Za-z0-9])#(([A-Za-z0-9]|[A-Za-z] \ [A-Za-z0-9-][A-Za-z0-9]).)+([A-Za-z0-9] \
|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])\b
Hostnames \b(([A-Za-z]|[A-Za-z][A-Za-z0-9-] \
[A-Za-z0-9]).)+([A-Za-z0-9] \ |[A-Za-z0-9][A-Za-z0-9-][A-Za-z0-9])\b
Node module for redacting data
https://github.com/watson/redact-secrets
Note: A coworker of mine did a great job of supplying me with a java sample of key value redacting in Java, using a regex to eliminate key values that contain `session,secret,token,password,passwd,connection' in xml and json, and quoted variants.
import java.security.GeneralSecurityException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Redact {
private static final String prefix = "[\"']?(session|(auth_)?token|password|passwd|secret|connection)[\"']?";
private static final String capture = "([\"']?)([\\w\\d!#$%()*+,-./:<=>?#[\\\\]^_`{|}~]+)([\"']?)";
private static Pattern pattern = Pattern.compile(prefix + "\\s*(=|:)\\s*" + capture, Pattern.CASE_INSENSITIVE);
public static String encryptSensitiveInfo(String message) {
try {
if (message == null)
return message;
StringBuffer newStr = new StringBuffer(message);
int lenDiff = 0;
Matcher m = pattern.matcher(message);
// Loop over message until all sensitive data is redacted
while (m.find()) {
String keyAndValue = m.group(0);
String value = m.group(5);
String REDACTED = "REDACTED";
String replacementText = keyAndValue.replace(value, REDACTED);
// Replace the key/value in the message with the new redacted
// value, adjusting for where it is in the redacted version of
// the input
newStr = newStr.replace(m.start() - lenDiff, m.end() - lenDiff, replacementText);
lenDiff += keyAndValue.length() - replacementText.length();
}
return newStr.toString();
} catch (Exception e) {
return message;
}
}
}

How to store public/private key securely

Looking to store public/private key information securely on an iOS device. I know I want to store this in the KeyChain however I am not 100% sure what sort of attributes I need to populate in the SecRecord. I was going to do something like:
// private key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Private,
CanSign = true,
ValueData = privateKeyValue,
Account = publicKeyValue
});
Which would store the private key, then follow a similar approach for the public key replacing the Account attribute with a value unique to the user e.g. username. However, not sure if this is the right way to use this.
Does anyone have a good examples on how you would do this specifically for keys?
Decided to go with the following approach:
// store public key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
ApplicationLabel = userName,
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Public,
ValueData = NSData.FromString(publicKey)
});
// store private key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
ApplicationLabel = publicKey,
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Private,
CanSign = true,
ValueData = NSData.FromString(secretKey)
});
This means each public key is mapped to an individual user and each private key is mapped to a public key which allows me to store multiple user keys (rather than only storing current logged in users).
Seems to work ok, however, still not 100% sure it is the correct way to do this kind of thing so some clarification would be nice.

Resources