Merge pull request #8125 from eugenp/revert-8119-BAEL-3275-2

Revert "BAEL-3275: Using blocking queue for pub-sub"
This commit is contained in:
Eric Martin
2019-10-31 20:43:47 -05:00
committed by GitHub
parent db85c8f275
commit 3225470df5
20543 changed files with 1642750 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
*.class
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear
/bin/
+12
View File
@@ -0,0 +1,12 @@
## Security
This module contains articles about security libraries.
### Relevant Articles:
- [Guide to ScribeJava](https://www.baeldung.com/scribejava)
- [Guide to Passay](https://www.baeldung.com/java-passay)
- [Guide to Google Tink](https://www.baeldung.com/google-tink)
- [Introduction to BouncyCastle with Java](https://www.baeldung.com/java-bouncy-castle)
- [Intro to Jasypt](https://www.baeldung.com/jasypt)
- [Digital Signature in Java](https://www.baeldung.com/java-digital-signature)
+89
View File
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>libraries-security</artifactId>
<name>libraries-security</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-1</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring-security-oauth2.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-apis</artifactId>
<version>${scribejava.version}</version>
</dependency>
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>${tink.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>${passay.version}</version>
</dependency>
<dependency>
<groupId>org.cryptacular</groupId>
<artifactId>cryptacular</artifactId>
<version>${cryptacular.version}</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>${jasypt.version}</version>
</dependency>
</dependencies>
<properties>
<spring-boot-maven-plugin.version>2.0.4.RELEASE</spring-boot-maven-plugin.version>
<scribejava.version>5.6.0</scribejava.version>
<spring-security-oauth2.version>2.3.3.RELEASE</spring-security-oauth2.version>
<passay.version>1.3.1</passay.version>
<tink.version>1.2.2</tink.version>
<cryptacular.version>1.2.2</cryptacular.version>
<jasypt.version>1.9.2</jasypt.version>
<bouncycastle.version>1.58</bouncycastle.version>
<spring.version>4.3.8.RELEASE</spring.version>
</properties>
</project>
@@ -0,0 +1,105 @@
package com.baeldung.bouncycastle;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.KeyTransRecipientInformation;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.OutputEncryptor;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
public class BouncyCastleCrypto {
public static byte[] signData(byte[] data, final X509Certificate signingCertificate, final PrivateKey signingKey) throws CertificateEncodingException, OperatorCreationException, CMSException, IOException {
byte[] signedMessage = null;
List<X509Certificate> certList = new ArrayList<X509Certificate>();
CMSTypedData cmsData = new CMSProcessableByteArray(data);
certList.add(signingCertificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator();
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey);
cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(contentSigner, signingCertificate));
cmsGenerator.addCertificates(certs);
CMSSignedData cms = cmsGenerator.generate(cmsData, true);
signedMessage = cms.getEncoded();
return signedMessage;
}
public static boolean verifSignData(final byte[] signedData) throws CMSException, IOException, OperatorCreationException, CertificateException {
ByteArrayInputStream bIn = new ByteArrayInputStream(signedData);
ASN1InputStream aIn = new ASN1InputStream(bIn);
CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject()));
aIn.close();
bIn.close();
Store certs = s.getCertificates();
SignerInformationStore signers = s.getSignerInfos();
Collection<SignerInformation> c = signers.getSigners();
SignerInformation signer = c.iterator().next();
Collection<X509CertificateHolder> certCollection = certs.getMatches(signer.getSID());
Iterator<X509CertificateHolder> certIt = certCollection.iterator();
X509CertificateHolder certHolder = certIt.next();
boolean verifResult = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder));
if (!verifResult) {
return false;
}
return true;
}
public static byte[] encryptData(final byte[] data, X509Certificate encryptionCertificate) throws CertificateEncodingException, CMSException, IOException {
byte[] encryptedData = null;
if (null != data && null != encryptionCertificate) {
CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator();
JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate);
cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey);
CMSTypedData msg = new CMSProcessableByteArray(data);
OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build();
CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor);
encryptedData = cmsEnvelopedData.getEncoded();
}
return encryptedData;
}
public static byte[] decryptData(final byte[] encryptedData, final PrivateKey decryptionKey) throws CMSException {
byte[] decryptedData = null;
if (null != encryptedData && null != decryptionKey) {
CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData);
Collection<RecipientInformation> recip = envelopedData.getRecipientInfos().getRecipients();
KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recip.iterator().next();
JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey);
decryptedData = recipientInfo.getContent(recipient);
}
return decryptedData;
}
}
@@ -0,0 +1,15 @@
package com.baeldung.scribejava;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ScribejavaApplication {
public static void main(String[] args) {
SpringApplication.run(ScribejavaApplication.class, args);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.scribejava.api;
import com.github.scribejava.core.builder.api.DefaultApi20;
public class MyApi extends DefaultApi20 {
private MyApi() {
}
private static class InstanceHolder {
private static final MyApi INSTANCE = new MyApi();
}
public static MyApi instance() {
return InstanceHolder.INSTANCE;
}
@Override
public String getAccessTokenEndpoint() {
return "http://localhost:8080/oauth/token";
}
@Override
protected String getAuthorizationBaseUrl() {
return null;
}
}
@@ -0,0 +1,49 @@
package com.baeldung.scribejava.controller;
import com.baeldung.scribejava.service.GoogleService;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
public class GoogleController {
@Autowired
private GoogleService service;
@GetMapping(value ="/me/google")
public void me(HttpServletResponse response){
String auth = service.getService().getAuthorizationUrl();
response.setHeader("Location", auth);
response.setStatus(302);
}
@GetMapping(value = "/auth/google")
public String google(@RequestParam String code, HttpServletResponse servletResponse){
try {
OAuth2AccessToken token = service.getService().getAccessToken(code);
OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json");
service.getService().signRequest(token, request);
Response response = service.getService().execute(request);
return response.getBody();
}catch (Exception e){
servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
return null;
}
}
@@ -0,0 +1,57 @@
package com.baeldung.scribejava.controller;
import com.baeldung.scribejava.service.TwitterService;
import com.github.scribejava.core.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
@RestController
public class TwitterController {
@Autowired
private TwitterService service;
@GetMapping(value ="/me/twitter")
public String me(HttpServletResponse servletResponse){
try {
OAuth1RequestToken requestToken = service.getService().getRequestToken();
String auth = service.getService().getAuthorizationUrl(requestToken);
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("rundll32 url.dll,FileProtocolHandler " + auth);
} catch (IOException e) {
servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return null;
}
System.out.println("Insert twitter code:");
Scanner in = new Scanner(System.in);
String oauthverifier = in.nextLine();
final OAuth1AccessToken accessToken = service.getService().getAccessToken(requestToken,oauthverifier);
OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.twitter.com/1.1/account/verify_credentials.json");
service.getService().signRequest(accessToken, request);
Response response = service.getService().execute(request);
return response.getBody();
} catch (IOException | InterruptedException | ExecutionException e) {
servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
return null;
}
}
@@ -0,0 +1,46 @@
package com.baeldung.scribejava.controller;
import com.baeldung.scribejava.service.MyService;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
@RestController(value = "/user")
public class UserController {
@Autowired
private MyService service;
@GetMapping("/me/myapi")
public String me(@RequestParam String username, @RequestParam String password, HttpServletResponse responsehttp) {
try {
OAuth2AccessToken token = service.getService().getAccessTokenPasswordGrant(username, password);
OAuthRequest request = new OAuthRequest(Verb.GET, "http://localhost:8080/me");
service.getService().signRequest(token, request);
Response response = service.getService().execute(request);
return response.getBody();
} catch (Exception e) {
responsehttp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
return null;
}
@GetMapping("/me")
public Principal user(Principal principal) {
return principal;
}
}
@@ -0,0 +1,45 @@
package com.baeldung.scribejava.oauth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
@Configuration
@EnableAuthorizationServer
public class AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("baeldung_api_key")
.secret("baeldung_api_secret")
.authorizedGrantTypes("password","refresh_token")
.scopes("read","write").autoApprove(true);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
}
@@ -0,0 +1,53 @@
package com.baeldung.scribejava.oauth;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
@Configuration
@EnableResourceServer
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().disable()
.and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("baeldung")
.password("scribejava")
.roles("USER");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@EnableResourceServer
@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/me").authenticated()
.and()
.csrf().disable();
}
}
}
@@ -0,0 +1,31 @@
package com.baeldung.scribejava.service;
import com.github.scribejava.apis.GoogleApi20;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.oauth.OAuth20Service;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class GoogleService {
private OAuth20Service service;
private final String API_KEY = "api_key";
private final String API_SECRET = "api_secret";
private final String SCOPE = "https://www.googleapis.com/auth/userinfo.email";
private final String CALLBACK = "http://localhost:8080/auth/google";
@PostConstruct
private void init(){
this.service = new ServiceBuilder(API_KEY)
.apiSecret(API_SECRET)
.scope(SCOPE)
.callback(CALLBACK)
.build(GoogleApi20.instance());
}
public OAuth20Service getService() {
return service;
}
}
@@ -0,0 +1,29 @@
package com.baeldung.scribejava.service;
import com.baeldung.scribejava.api.MyApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.oauth.OAuth20Service;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MyService {
private OAuth20Service service;
private final String API_KEY = "baeldung_api_key";
private final String API_SECRET = "baeldung_api_secret";
@PostConstruct
private void init(){
this.service = new ServiceBuilder(API_KEY)
.apiSecret(API_SECRET)
.scope("read write")
.build(MyApi.instance());
}
public OAuth20Service getService() {
return service;
}
}
@@ -0,0 +1,29 @@
package com.baeldung.scribejava.service;
import com.github.scribejava.apis.TwitterApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.oauth.OAuth10aService;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class TwitterService {
private final String API_KEY = "api_key";
private final String API_SECRET = "api_secret";
private OAuth10aService service;
@PostConstruct
private void init(){
this.service = new ServiceBuilder(API_KEY)
.apiSecret(API_SECRET)
.build(TwitterApi.instance());
}
public OAuth10aService getService(){
return service;
}
}
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw
DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa
MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh
YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh
jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM
AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr
CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj
fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV
whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR
BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB
AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1
vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP
pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU
CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt
XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU
ia7y5BL6uOa/4ShSV8pcJDYz
-----END CERTIFICATE-----
@@ -0,0 +1 @@
security.oauth2.resource.filter-order = 3
@@ -0,0 +1,50 @@
package com.baeldung.bouncycastle;
import static org.junit.Assert.assertTrue;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.junit.Test;
public class BouncyCastleLiveTest {
String certificatePath = "src/main/resources/Baeldung.cer";
String privateKeyPath = "src/main/resources/Baeldung.p12";
char[] p12Password = "password".toCharArray();
char[] keyPassword = "password".toCharArray();
@Test
public void givenCryptographicResource_whenOperationSuccess_returnTrue() throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, IOException, KeyStoreException, UnrecoverableKeyException, CMSException, OperatorCreationException {
Security.addProvider(new BouncyCastleProvider());
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(new FileInputStream(certificatePath));
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(privateKeyPath), p12Password);
PrivateKey privateKey = (PrivateKey) keystore.getKey("baeldung", keyPassword);
String secretMessage = "My password is 123456Seven";
System.out.println("Original Message : " + secretMessage);
byte[] stringToEncrypt = secretMessage.getBytes();
byte[] encryptedData = BouncyCastleCrypto.encryptData(stringToEncrypt, certificate);
byte[] rawData = BouncyCastleCrypto.decryptData(encryptedData, privateKey);
String decryptedMessage = new String(rawData);
assertTrue(decryptedMessage.equals(secretMessage));
byte[] signedData = BouncyCastleCrypto.signData(rawData, certificate, privateKey);
Boolean check = BouncyCastleCrypto.verifSignData(signedData);
assertTrue(check);
}
}
@@ -0,0 +1,95 @@
package com.baeldung.jasypt;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.util.password.BasicPasswordEncryptor;
import org.jasypt.util.text.BasicTextEncryptor;
import org.junit.Ignore;
import org.junit.Test;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;
public class JasyptUnitTest {
@Test
public void givenTextPrivateData_whenDecrypt_thenCompareToEncrypted() {
// given
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
String privateData = "secret-data";
textEncryptor.setPasswordCharArray("some-random-data".toCharArray());
// when
String myEncryptedText = textEncryptor.encrypt(privateData);
assertNotSame(privateData, myEncryptedText); // myEncryptedText can be save in db
// then
String plainText = textEncryptor.decrypt(myEncryptedText);
assertEquals(plainText, privateData);
}
@Test
public void givenTextPassword_whenOneWayEncryption_thenCompareEncryptedPasswordsShouldBeSame() {
String password = "secret-pass";
BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(password);
// when
boolean result = passwordEncryptor.checkPassword("secret-pass", encryptedPassword);
// then
assertTrue(result);
}
@Test
public void givenTextPassword_whenOneWayEncryption_thenCompareEncryptedPasswordsShouldNotBeSame() {
String password = "secret-pass";
BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(password);
// when
boolean result = passwordEncryptor.checkPassword("secret-pass-not-same", encryptedPassword);
// then
assertFalse(result);
}
@Test
@Ignore("should have installed local_policy.jar")
public void givenTextPrivateData_whenDecrypt_thenCompareToEncryptedWithCustomAlgorithm() {
// given
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
String privateData = "secret-data";
encryptor.setPassword("some-random-data");
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");
// when
String encryptedText = encryptor.encrypt("secret-pass");
assertNotSame(privateData, encryptedText);
// then
String plainText = encryptor.decrypt(encryptedText);
assertEquals(plainText, privateData);
}
@Test
@Ignore("should have installed local_policy.jar")
public void givenTextPrivateData_whenDecryptOnHighPerformance_thenDecrypt() {
// given
String privateData = "secret-data";
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setPoolSize(4);
encryptor.setPassword("some-random-data");
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");
// when
String encryptedText = encryptor.encrypt(privateData);
assertNotSame(privateData, encryptedText);
// then
String plainText = encryptor.decrypt(encryptedText);
assertEquals(plainText, privateData);
}
}
@@ -0,0 +1,149 @@
package com.baeldung.passay;
import org.cryptacular.bean.EncodingHashBean;
import org.cryptacular.spec.CodecSpec;
import org.cryptacular.spec.DigestSpec;
import org.junit.Assert;
import org.junit.Test;
import org.passay.DictionaryRule;
import org.passay.DictionarySubstringRule;
import org.passay.DigestHistoryRule;
import org.passay.EnglishSequenceData;
import org.passay.HistoryRule;
import org.passay.IllegalCharacterRule;
import org.passay.IllegalRegexRule;
import org.passay.IllegalSequenceRule;
import org.passay.NumberRangeRule;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RepeatCharacterRegexRule;
import org.passay.RuleResult;
import org.passay.SourceRule;
import org.passay.UsernameRule;
import org.passay.WhitespaceRule;
import org.passay.dictionary.ArrayWordList;
import org.passay.dictionary.WordListDictionary;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class NegativeMatchingRulesUnitTest {
@Test
public void givenDictionaryRules_whenValidatePassword_thenFoundIllegalWordsFromDictionary() {
ArrayWordList arrayWordList = new ArrayWordList(new String[] { "bar", "foobar" });
WordListDictionary wordListDictionary = new WordListDictionary(arrayWordList);
DictionaryRule dictionaryRule = new DictionaryRule(wordListDictionary);
DictionarySubstringRule dictionarySubstringRule = new DictionarySubstringRule(wordListDictionary);
PasswordValidator passwordValidator = new PasswordValidator(dictionaryRule, dictionarySubstringRule);
RuleResult validate = passwordValidator.validate(new PasswordData("foobar"));
assertFalse(validate.isValid());
assertEquals("ILLEGAL_WORD:{matchingWord=foobar}", getDetail(validate, 0));
assertEquals("ILLEGAL_WORD:{matchingWord=bar}", getDetail(validate, 1));
}
@Test
public void givenHistoryRule_whenValidatePassword_thenFoundIllegalWordsFromHistory() {
HistoryRule historyRule = new HistoryRule();
PasswordData passwordData = new PasswordData("123");
passwordData.setPasswordReferences(new PasswordData.HistoricalReference("12345"), new PasswordData.HistoricalReference("1234"), new PasswordData.HistoricalReference("123"));
PasswordValidator passwordValidator = new PasswordValidator(historyRule);
RuleResult validate = passwordValidator.validate(passwordData);
assertFalse(validate.isValid());
assertEquals("HISTORY_VIOLATION:{historySize=3}", getDetail(validate, 0));
}
@Test
public void givenSeveralIllegalRules_whenValidatePassword_thenFoundSeveralIllegalPatterns() {
IllegalCharacterRule illegalCharacterRule = new IllegalCharacterRule(new char[] { 'a' });
IllegalRegexRule illegalRegexRule = new IllegalRegexRule("\\w{2}\\d{2}");
IllegalSequenceRule illegalSequenceRule = new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 3, true);
NumberRangeRule numberRangeRule = new NumberRangeRule(1, 10);
WhitespaceRule whitespaceRule = new WhitespaceRule();
PasswordValidator passwordValidator = new PasswordValidator(illegalCharacterRule, illegalRegexRule, illegalSequenceRule, numberRangeRule, whitespaceRule);
RuleResult validate = passwordValidator.validate(new PasswordData("abcd22 "));
assertFalse(validate.isValid());
assertEquals("ILLEGAL_CHAR:{illegalCharacter=a, matchBehavior=contains}", getDetail(validate, 0));
assertEquals("ILLEGAL_MATCH:{match=cd22, pattern=\\w{2}\\d{2}}", getDetail(validate, 1));
assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=abc}", getDetail(validate, 2));
assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=bcd}", getDetail(validate, 3));
assertEquals("ILLEGAL_NUMBER_RANGE:{number=2, matchBehavior=contains}", getDetail(validate, 4));
assertEquals("ILLEGAL_WHITESPACE:{whitespaceCharacter= , matchBehavior=contains}", getDetail(validate, 5));
}
@Test
public void givenSourceRule_whenValidatePassword_thenFoundIllegalWordsFromSource() {
SourceRule sourceRule = new SourceRule();
PasswordData passwordData = new PasswordData("password");
passwordData.setPasswordReferences(new PasswordData.SourceReference("source", "password"));
PasswordValidator passwordValidator = new PasswordValidator(sourceRule);
RuleResult validate = passwordValidator.validate(passwordData);
assertFalse(validate.isValid());
assertEquals("SOURCE_VIOLATION:{source=source}", getDetail(validate, 0));
}
@Test
public void givenRepeatCharacterRegexRuleRule_whenValidatePassword_thenFoundIllegalPatternMatches() {
RepeatCharacterRegexRule repeatCharacterRegexRule = new RepeatCharacterRegexRule(3);
PasswordValidator passwordValidator = new PasswordValidator(repeatCharacterRegexRule);
RuleResult validate = passwordValidator.validate(new PasswordData("aaabbb"));
assertFalse(validate.isValid());
assertEquals("ILLEGAL_MATCH:{match=aaa, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 0));
assertEquals("ILLEGAL_MATCH:{match=bbb, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 1));
}
@Test
public void givenUserNameRule_whenValidatePassword_thenFoundUserNameInPassword() {
PasswordValidator passwordValidator = new PasswordValidator(new UsernameRule());
PasswordData passwordData = new PasswordData("testuser1234");
passwordData.setUsername("testuser");
RuleResult validate = passwordValidator.validate(passwordData);
assertFalse(validate.isValid());
assertEquals("ILLEGAL_USERNAME:{username=testuser, matchBehavior=contains}", getDetail(validate, 0));
}
@Test
public void givenPasswordAndHashBeanAndEncryptedReferences_whenValidate_thenPasswordValidationShouldPass() {
List<PasswordData.Reference> historicalReferences = Arrays.asList(new PasswordData.HistoricalReference("SHA256", "2e4551de804e27aacf20f9df5be3e8cd384ed64488b21ab079fb58e8c90068ab"));
PasswordData passwordData = new PasswordData("example!");
passwordData.setPasswordReferences(historicalReferences);
EncodingHashBean encodingHashBean = new EncodingHashBean(new CodecSpec("Base64"), new DigestSpec("SHA256"), 1, false);
PasswordValidator passwordValidator = new PasswordValidator(new DigestHistoryRule(encodingHashBean));
RuleResult validate = passwordValidator.validate(passwordData);
Assert.assertTrue(validate.isValid());
}
private String getDetail(RuleResult validate, int i) {
return validate.getDetails()
.get(i)
.toString();
}
}
@@ -0,0 +1,50 @@
package com.baeldung.passay;
import org.junit.Assert;
import org.junit.Test;
import org.passay.CharacterData;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.PasswordGenerator;
import java.util.stream.Stream;
public class PasswordGeneratorUnitTest {
@Test
public void givenDigitsGenerator_whenGeneratingPassword_thenPasswordContainsDigitsHasLength10() {
CharacterRule digits = new CharacterRule(EnglishCharacterData.Digit);
PasswordGenerator passwordGenerator = new PasswordGenerator();
String password = passwordGenerator.generatePassword(10, digits);
Assert.assertTrue(password.length() == 10);
Assert.assertTrue(containsOnlyCharactersFromSet(password, "0123456789"));
}
@Test
public void givenCustomizedRule_whenGenerating_thenGeneratedPasswordContainsCustomizedCharacters() {
CharacterRule specialCharacterRule = new CharacterRule(new CharacterData() {
@Override
public String getErrorCode() {
return "SAMPLE_ERROR_CODE";
}
@Override
public String getCharacters() {
return "ABCxyz123!@#";
}
});
PasswordGenerator passwordGenerator = new PasswordGenerator();
String password = passwordGenerator.generatePassword(10, specialCharacterRule);
Assert.assertTrue(containsOnlyCharactersFromSet(password, "ABCxyz123!@#"));
}
private boolean containsOnlyCharactersFromSet(String password, String setOfCharacters) {
return Stream.of(password.split(""))
.allMatch(it -> setOfCharacters.contains(it));
}
}
@@ -0,0 +1,81 @@
package com.baeldung.passay;
import org.junit.Assert;
import org.junit.Test;
import org.passay.LengthRule;
import org.passay.MessageResolver;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.PropertiesMessageResolver;
import org.passay.RuleResult;
import org.passay.RuleResultDetail;
import org.passay.RuleResultMetadata;
import org.passay.WhitespaceRule;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class PasswordValidatorUnitTest {
@Test
public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooShortPassword() {
PasswordData passwordData = new PasswordData("1234");
PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5));
RuleResult validate = passwordValidator.validate(passwordData);
assertEquals(false, validate.isValid());
RuleResultDetail ruleResultDetail = validate.getDetails()
.get(0);
assertEquals("TOO_SHORT", ruleResultDetail.getErrorCode());
assertEquals(5, ruleResultDetail.getParameters()
.get("minimumLength"));
assertEquals(5, ruleResultDetail.getParameters()
.get("maximumLength"));
Integer lengthCount = validate.getMetadata()
.getCounts()
.get(RuleResultMetadata.CountCategory.Length);
assertEquals(Integer.valueOf(4), lengthCount);
}
@Test
public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooLongPassword() {
PasswordData passwordData = new PasswordData("123456");
PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5));
RuleResult validate = passwordValidator.validate(passwordData);
assertFalse(validate.isValid());
Assert.assertEquals("TOO_LONG", validate.getDetails()
.get(0)
.getErrorCode());
}
@Test
public void givenPasswordValidatorWithLengthRule_whenValidation_thenCustomizedMeesagesAvailable() throws IOException {
URL resource = this.getClass()
.getClassLoader()
.getResource("messages.properties");
Properties props = new Properties();
props.load(new FileInputStream(resource.getPath()));
MessageResolver resolver = new PropertiesMessageResolver(props);
PasswordValidator validator = new PasswordValidator(resolver, new LengthRule(8, 16), new WhitespaceRule());
RuleResult tooShort = validator.validate(new PasswordData("XXXX"));
RuleResult tooLong = validator.validate(new PasswordData("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"));
assertEquals("Password must not contain less characters than 16.", validator.getMessages(tooShort)
.get(0));
assertEquals("Password must not have more characters than 16.", validator.getMessages(tooLong)
.get(0));
}
}
@@ -0,0 +1,76 @@
package com.baeldung.passay;
import org.junit.Test;
import org.passay.AllowedCharacterRule;
import org.passay.AllowedRegexRule;
import org.passay.CharacterCharacteristicsRule;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.LengthComplexityRule;
import org.passay.LengthRule;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RuleResult;
import static org.junit.Assert.*;
public class PositiveMatchingRulesUnitTest {
@Test
public void givenPasswordValidationRules_whenValidatingPassword_thenPosswordIsNotValidWithSeveralErrors() {
PasswordValidator passwordValidator = new PasswordValidator(new AllowedCharacterRule(new char[] { 'a', 'b', 'c' }), new AllowedRegexRule("\\d{2}\\w{10}"), new CharacterRule(EnglishCharacterData.LowerCase, 5), new LengthRule(8, 10));
RuleResult validate = passwordValidator.validate(new PasswordData("12abc"));
assertFalse(validate.isValid());
assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validate, 0));
assertEquals("ALLOWED_CHAR:{illegalCharacter=2, matchBehavior=contains}", getDetail(validate, 1));
assertEquals("ALLOWED_MATCH:{pattern=\\d{2}\\w{10}}", getDetail(validate, 2));
assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, matchingCharacterCount=3, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=abc}", getDetail(validate, 3));
assertEquals("TOO_SHORT:{minimumLength=8, maximumLength=10}", getDetail(validate, 4));
}
@Test
public void givenRulesForDifferentPasswordLength_whenValidatingTwoDifferentPassword_thenBothOfThemAreInvalid() {
PasswordData shortPassword = new PasswordData("12ab");
PasswordData longPassword = new PasswordData("1234abcde");
LengthComplexityRule lengthComplexityRule = new LengthComplexityRule();
lengthComplexityRule.addRules("[1,5]", new CharacterRule(EnglishCharacterData.LowerCase, 5));
lengthComplexityRule.addRules("[6,10]", new AllowedCharacterRule(new char[] { 'a', 'b', 'c', 'd' }));
PasswordValidator passwordValidator = new PasswordValidator(lengthComplexityRule);
RuleResult validateShort = passwordValidator.validate(shortPassword);
RuleResult validateLong = passwordValidator.validate(longPassword);
assertFalse(validateShort.isValid());
assertFalse(validateLong.isValid());
assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=2, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=ab}", getDetail(validateShort, 0));
assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validateLong, 0));
}
@Test
public void givenCharacterCharacteristicsRule_whenValidatingPassword_thenItIsInvalidAsItBreaksToManyRules() {
PasswordData shortPassword = new PasswordData();
shortPassword.setPassword("12345abcde!");
CharacterCharacteristicsRule characterCharacteristicsRule = new CharacterCharacteristicsRule(4, new CharacterRule(EnglishCharacterData.LowerCase, 5), new CharacterRule(EnglishCharacterData.UpperCase, 5), new CharacterRule(EnglishCharacterData.Digit),
new CharacterRule(EnglishCharacterData.Special));
PasswordValidator passwordValidator = new PasswordValidator(characterCharacteristicsRule);
RuleResult validate = passwordValidator.validate(shortPassword);
assertFalse(validate.isValid());
assertEquals("INSUFFICIENT_UPPERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=0, " + "validCharacters=ABCDEFGHIJKLMNOPQRSTUVWXYZ, " + "matchingCharacters=}", getDetail(validate, 0));
assertEquals("INSUFFICIENT_CHARACTERISTICS:{" + "successCount=3, " + "minimumRequired=4, " + "ruleCount=4}", getDetail(validate, 1));
}
private String getDetail(RuleResult validate, int i) {
return validate.getDetails()
.get(i)
.toString();
}
}
@@ -0,0 +1,17 @@
package com.baeldung.scribejava;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ScribejavaUnitTest {
@Test
public void contextLoad(){
}
}
@@ -0,0 +1,103 @@
package com.baeldung.tink;
import com.google.crypto.tink.*;
import com.google.crypto.tink.aead.AeadConfig;
import com.google.crypto.tink.aead.AeadFactory;
import com.google.crypto.tink.aead.AeadKeyTemplates;
import com.google.crypto.tink.config.TinkConfig;
import com.google.crypto.tink.hybrid.HybridDecryptFactory;
import com.google.crypto.tink.hybrid.HybridEncryptFactory;
import com.google.crypto.tink.hybrid.HybridKeyTemplates;
import com.google.crypto.tink.mac.MacFactory;
import com.google.crypto.tink.mac.MacKeyTemplates;
import com.google.crypto.tink.signature.PublicKeySignFactory;
import com.google.crypto.tink.signature.PublicKeyVerifyFactory;
import com.google.crypto.tink.signature.SignatureKeyTemplates;
import org.junit.Assert;
import org.junit.Test;
import java.security.GeneralSecurityException;
public class TinkLiveTest {
//need to download policy files and put them into ${java.home}/jre/lib/security/
private static final String PLAINTEXT = "BAELDUNG";
private static final String DATA = "TINK";
@Test
public void givenPlaintext_whenEncryptWithAead_thenPlaintextIsEncrypted() throws GeneralSecurityException {
AeadConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.AES256_GCM);
Aead aead = AeadFactory.getPrimitive(keysetHandle);
byte[] ciphertext = aead.encrypt(PLAINTEXT.getBytes(),
DATA.getBytes());
Assert.assertNotEquals(PLAINTEXT, new String(ciphertext));
}
@Test
public void givenData_whenComputeMAC_thenVerifyMAC() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
MacKeyTemplates.HMAC_SHA256_128BITTAG);
Mac mac = MacFactory.getPrimitive(keysetHandle);
byte[] tag = mac.computeMac(DATA.getBytes());
mac.verifyMac(tag, DATA.getBytes());
}
@Test
public void givenData_whenSignData_thenVerifySignature() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
SignatureKeyTemplates.ECDSA_P256);
PublicKeySign signer = PublicKeySignFactory.getPrimitive(privateKeysetHandle);
byte[] signature = signer.sign(DATA.getBytes());
KeysetHandle publicKeysetHandle =
privateKeysetHandle.getPublicKeysetHandle();
PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive(publicKeysetHandle);
verifier.verify(signature, DATA.getBytes());
}
@Test
public void givenPlaintext_whenEncryptWithHybridEncryption_thenVerifyDecryptedIsEqual() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256);
KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle();
HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle);
HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(privateKeysetHandle);
String contextInfo = "Tink";
byte[] ciphertext = hybridEncrypt.encrypt(PLAINTEXT.getBytes(), contextInfo.getBytes());
byte[] plaintextDecrypted = hybridDecrypt.decrypt(ciphertext, contextInfo.getBytes());
Assert.assertEquals(PLAINTEXT,new String(plaintextDecrypted));
}
}
@@ -0,0 +1,2 @@
TOO_LONG=Password must not have more characters than %2$s.
TOO_SHORT=Password must not contain less characters than %2$s.