Thursday, March 30, 2023

Spring security - 0.001 :)



spring. boot-starter-security-> allows defining credentials in application properties. 
Add below in pom . application for boot applicatoins


adding below security.  properties : which makes applications ask for these credentials (Un safe as the credentials are in text file)


will ask for the credentials to see the boot application from now.


Step2 ) 

as exposing in text file as above is vulnerable, use spring security config

using. @EnableWebSecurity annotation and extend WebSeucirtyConfigurerAdapter class . Then implement global configureGlobal function with the credential details.


Update global credentials instead of placing in application properties file using AuthenticationManagerBuilder as above.

and create a new object by calling in the main Boot Class to create instance as below



This also enables Spring to generate an autogenerated Form which asks for credentials and the user is allowed only when the credentials are correct. (Unlike Step1 -> Where browser pop-up will come)


if the above POM file changes are not recognising and not giving the login form for application properties change, then 

add the below one and check (also if not using Boot, you need to define the following dependencies)

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>


3) Another way of doing this is to implement other than mentioning in properties file
@EnableWebSecurity
public class LssSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("USER");
}
}

please observe that {noop} need to be mentioned along with the password 
otherwise, this will give below exception 
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
	at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:289)
	at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:237)
	at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration$LazyPasswordEncoder.matches(AuthenticationConfiguration.java:313)


and to make URL level authentication in override Configure fucntion of WebSecurityCongirurerAdapter

as below
@EnableWebSecurity
public class LssSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

try {
http.authorizeRequests().anyRequest().
authenticated().
antMatchers("/delete/**").
hasAnyAuthority("ADMIN").and().formLogin();
http.httpBasic();
} catch (Exception e) {
e.printStackTrace();
}
}
}

This makes for all Delete operations the user role should be of ADMIN type. 

Monday, March 6, 2023

jks keytool commands

# 1. Create a Java Key Store (JKS) with Private & Public key pairs using keytool
#
-------------------------------------------------------------------------------#
# Keytool '-genkeypair' option used, in earlier version of keytool '-genkey' option was used which is still supported for backward compatibility
# Following command generates a RSA 2048 bit Public and Private key pair, wraps the public key into an X.509 v3 self-signed certificate signed by SHA256withRSA with a validity period of 365 days, which is then stored as a single-element certificate chain. This certificate chain and the private key are stored in a new keystore 'sample_keystore.jks' entry identified by alias 'sample'.
# Option defaults:
# -alias: mykey
# -keyalg: DSA
# -keysize: 2048 bit (for both RSA and DSA)
# -validity: 90 days
# -storetype: JKS (property value fetched from 'java.security.keystore.type' from Java jdk/jre)
# Ref: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#keytool_option_genkeypair
keytool -genkeypair -v -alias sample -keyalg RSA -keysize 2048 \
-dname "CN=sample.com, OU=apim, O=wso2, L=colombo, ST=western, C=lk" -validity 365 -keypass abcd@1234 -storepass abcd@1234 \
-keystore sample_keystore.jks
# 2. Create a JKS with Private & Public key pairs including SANs, IPs, KeyUsages & ExtendedKeyUsages using keytool
#-----------------------------------------------------------------------------------------------------------------#
# Keytool extension '-ext' option used to provide 'SAN', 'IP', 'KeyUsage' and 'ExtendedKeyUsage'
# Note:
# Using JDKs below JDK15, it is not possible to generate a JKS 'passing wildcard SAN extension' with keytool
# Example, with JDK8, 'dns:*.efs.eu-west-1.amazonaws.com' Or 'dns:test.*.eu-west-1.amazonaws.com' will result in an error
# This has been fixed with JDK15, https://bugs.openjdk.java.net/browse/JDK-8186143
keytool -genkeypair -v -alias sample -keyalg RSA -keysize 2048 \
-dname "CN=sample.com, OU=apim, O=wso2, L=colombo, ST=western, C=lk" \
-ext "san=dns:test.sample.com,dns:test.efs.eu-west-1.amazonaws.com,dns:localhost,ip:127.0.0.1" \
-ext KeyUsage=digitalSignature,keyEncipherment,dataEncipherment,nonRepudiation,keyCertSign \
-ext ExtendedKeyUsage=serverAuth,clientAuth -validity 365 -keypass abcd@1234 -storepass abcd@1234 \
-keystore sample_keystore.jks
# 3. List entries of JKS
#-----------------------#
keytool -list -v -keystore sample_keystore.jks
# 4. Converting a JKS to PKCS12 keystore
#---------------------------------------#
keytool -importkeystore -srckeystore sample_keystore.jks -destkeystore sample_keystore.pfx -deststoretype pkcs12
# 5. Export public certificate from JKS in DER format (binary-encoded format)
#----------------------------------------------------------------------------#
keytool -exportcert -alias sample -file sample.crt -keystore sample_keystore.jks
# 6. Export public certificate from JKS in PEM format (ASCII Base64 human-readble format)
#----------------------------------------------------------------------------------------#
# Additional '-rfc' option need to be passed along with '-exportcert' option to get a pem encoded certificate
keytool -exportcert -alias sample -file sample.pem -keystore sample_keystore.jks -rfc
# 7. Import third-party public certificates to the JKS
#-----------------------------------------------------#
# Third party public certificates are imported as Trusted CA certificates
keytool -import -trustcacerts -alias wso2carbon -file wso2carbon.pem -keystore sample_keystore.jks
# 8. Export private key entry from JKS
#-------------------------------------#
# By default, the JKS key store type doesn't support exporting the Private key entry using the key tool
# Private key entry can be exported by converting the JKS to a PKCS12 key store
# Command for converting JKS to PKCS12 key store can be found in 4
# We will use the PKCS12 key store 'sample_keystore.pfx' and export the private key entry in 'PEM' format using the following OpenSSL command
# Options:
# -nodes: No DES format so the Private key won't be encrypted
# -nocerts: No certificates will be exported at all, only the private key entry
openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts -out sample_keystore_private_key.pem
# 9. Convert the private key entry from 'PEM' encoding to 'DER' encoding
#-----------------------------------------------------------------------#
# By default, OpenSSL command saves the private key entry (encrypted/unencrypted) to the file using the 'PEM' encoding
# We can convert the 'PEM' format to 'DER' format using openssl 'pkey','-inform' and '-outform' options
openssl pkey -in sample_keystore_private_key.pem -inform pem -out sample_keystore_private_key.der -outform der
# 10. Export the Triple-DES encrypted private key entry from the JKS
#-------------------------------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# By default, if the 'encryption algorithm' is not specified explicitly Or the '-nodes' options is not passed, OpenSSL will encrypt the private key entry using '3DES encryption algorithm'
# Following exports the 'PEM' encoded '3DES encrypted' private key entry
openssl pkcs12 -in sample_keystore.pfx -nocerts -out sample_keystore_private_key_default_enc.pem
# 11. Export the 'AES256' encrypted private key entry from the JKS
#---------------------------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# We can explicitly pass the encryption algorithm as an argument (ex: -aes256)
# Apart from using the 'default 3DES algorithm', we can export the encrypted Private key entry by specifying one of the following encryption algorithms.
# AES (aes128, aes192, aes256) => -aes128, -aes192, -aes256
# DES => -des
# 3DES => -des3
openssl pkcs12 -in sample_keystore.pfx -aes256 -nocerts -out sample_keystore_private_key_aes256.pem
# 12. Export the 'RSAPrivateKey' from the JKS
#--------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# Private key entry contains 'Bag Attributes' and 'Key Attributes' apart from the 'Encrypted/Un-encrypted RSAPrivateKey'
# 'RSAPrivateKey' ASN.1 structure defined in 'PKCS#1 (RFC 3447)' allows the private key entry to only contain the private key eliminating the 'Bag Attributes' and 'Key Attributes'.
# 'RSAPrivateKey' contains -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- tags
# Following command will extract an unencrypted RSA private key from the JKS without other attributes
openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts | openssl rsa -out sample_keystore_private_key_rsa.pem
# 13. Extracting 'RSAPrivateKey' from the 'PKCS#8' private key entry
#-------------------------------------------------------------------#
# Older versions of OpenSSL generated private key entry (not RSA private key) in 'PKCS#1', newer versions in 'PKCS#8'
# Following command extracts the 'RSAPrivateKey' from an existing private key entry
openssl rsa -in sample_keystore_private_key.pem -out sample_keystore_private_key_rsa_converted.pem
# 14. Extracting Triple DES encrypted 'RSAPrivateKey' from the 'PKCS#8' private key entry
#----------------------------------------------------------------------------------------#
# RSA private key exported nonencrypted poses a security threat
# Following command extracts a 'RSAPrivateKey' from a 'PKCS#8' private key entry in a Triple DES encrypted format
# Note:
# 'Proc-Type: 4,ENCRYPTED' attribute which shows us the RSA private key entry is encrypted.
openssl rsa -in sample_keystore_private_key.pem -des3 -out sample_keystore_private_key_rsa_des3.pem
# 15. Import a private key entry to JKS
#--------------------------------------#
# It is not possible to directly import private key entry to JKS
# We can import the private key to a 'PKCS12' key store and convert it to a 'JKS' key store
# Following command exports the private key, public certificate and certificate chain as a 'PKCS12' keystore
# Be sure to set an export password to avoid NullPointerException
openssl pkcs12 -export -in <public_cert>.crt -inkey <private_key>.key -chain -CAfile <ca_cert>.crt \
-name "sample.com" -out sample_keystore_pkcs12.p12
# Following command converts the 'PKCS12' key store to a JKS
keytool -importkeystore -srckeystore sample_keystore_pkcs12.p12 -srcstoretype PKCS12 \
-destkeystore sample_keystore_with_imported_private_key.jks -deststoretype JKS -deststorepass abcd@1234
# 16. Generating JKS with 'Secret Key' entry
#-------------------------------------------#
# According to the JKS key store specification, we can't store 'non-PrivateKeys' in a 'JKS' type key store.
# Let's try to generate a JKS with secret key entry using the below command
# Note:
# -genseckey: Option is used to generate the Secret key.
# -keyalg: Argument is used to pass the Secret key algorithm.
# Common secret key algorithms include DES, 3DES, and AES.
keytool -genseckey -alias secretKey -keypass secretKey -keyalg AES -keysize 256 \
-keystore secretKey.jks -storepass secretKey -storetype JKS -v
# The above command will result in an error with an exception
# keytool error: java.security.KeyStoreException: Cannot store non-PrivateKeys
# It is not possible to generate Or import Courtesy: https://techexpertise.medium.com/exploring-key-stores-and-public-certificates-jks-723eb6b32a21