Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@FrankGasparovic
Copy link

No description provided.

Copy link
Contributor

@sanjeevchopra sanjeevchopra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you rebase from the branch which has the ConnectorService, so you can invoke the encryption/decryption ? or we can wait for that branch to merge to develop.

byte[] result = Bytes.concat(ivBytes, encrypted);

return Base64.encodeBase64String(result);
} catch (Exception ex) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • catch Throwable to be safe
  • pls remove the printStackTrace
  • log a error (excluding the encryption key)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created custom exceptions based on the error and added log statements.


public String encrypt(final String value) {
try {
if (this.key.length() != 24) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any other requirements on the key ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I know of. We are doing 192 bit encryption, the key just needs to have that number of bits and we should be good to go.

@Configuration
public class EncryptionConfig {

@Value("${ENCRYPTION_KEY}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if we should use a obscure name for obfuscation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obfuscation from who? If someone is able to see our environment variables in cf, they are already a privileged user.

}
}

public String decrypt(final String encrypted) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments from encrypt apply here as well

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the key and cipher setup be done once in the constructor ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Moved.


import com.google.common.primitives.Bytes;

public class AcsEncryption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AESEncrypter ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with Encryptor

@@ -0,0 +1,9 @@
package com.ge.predix.acs.encryption;

public interface Encryptor {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make this generally usable, we could build this as a credential store interface. It has 2 functions storage and encryption/decryption. This service could be used as-is with audit or any other credential which ACS needs to store.

`public interface CredentialStore {

String encryptAndStore(String id, String key, String value);

String findAndDecrypt(String id, String key, String encrypted);

}`

  • id - will be used for lookup and storage
  • key - for encryption/decryption OR authN token in case of vault)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed with Frank. Doesnt quite work because when using a store, you dont really have a 'encrypted value'. Probably best as 2 separate services - Encryptor and SecureStorage. You only need one or the other (Encryptor + regular storage OR SecureStorage)

@FrankGasparovic FrankGasparovic force-pushed the US92112 branch 4 times, most recently from a506d69 to 13189f0 Compare March 15, 2017 19:53
Set<AttributeAdapterConnection> attributeAdapterConnections = new HashSet<>();
connector.getAdapters().parallelStream().forEach(a -> {
a.setUaaClientSecret(this.encryptor.encrypt(a.getUaaClientSecret()));
attributeAdapterConnections.add(a);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • why do you need a new set of connections ? the secret is already updated by reference
  • pls make sure HashSet indeed supports parallel streams
  • code will read better if you rename a to adapterConnection

return this.connectorConverter.toConnector(zoneEntity.getResourceAttributeConnector());
AttributeConnector connector = this.connectorConverter.toConnector(zoneEntity.getResourceAttributeConnector());
if (null != connector) {
Set<AttributeAdapterConnection> attributeAdapterConnections = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comments as upsert

private String adapterClientId;

@Transient
@Column(name = "adapter_client_secret", nullable = false, length = 128)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the encryption algo produce a value of the same length ? Just making sure if 128 is the appropriate lenght

import com.ge.predix.acs.encryption.Encryptor;

@Configuration
public class EncryptionConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this class and make Encryptor a spring bean.

  • Also AttributeAdatperConnectionEntity should have a transient getUaaClientSecret() which returns the decrypted secret
  • The persistent field can be renamed to something like getEncryptedUaaClientSecret() (the whole entity is changing to transient now based on our json change)

this.cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

byte[] encrypted = this.cipher.doFinal(value.getBytes());
byte[] result = Bytes.concat(ivBytes, encrypted);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is limited value to concat'ing a salt here, given we our code is open source. If we keep it, pls add some comments to explain the steps here.

Copy link
Collaborator

@irinaepshteyn irinaepshteyn Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IV is required by CBC cipher mode. We could switch to using ECB instead and then IV will not be required. ECB is considered weaker than CBC since the same blocks of plain text encrypted with ECB result in the same encrypted blocks.

Copy link
Contributor

@sanjeevchopra sanjeevchopra Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frank, explained that this is useful to prevent against dictionary attacks. Lets keep it and add some comments here 👍

@Test
public void testEncryptCompleteFlow() {
Encryptor encryption = Encryptor.getInstance();
ReflectionTestUtils.setField(encryption, ENCRYPTION_KEY_VAR_NAME, "FooBarFooBarFooB");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.asertNotEquals(encryption.encrypt(VALUE_TO_ENCRYPT), VALUE_TO_ENCRYPT)

this.cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

byte[] encrypted = this.cipher.doFinal(value.getBytes());
byte[] result = Bytes.concat(ivBytes, encrypted);
Copy link
Contributor

@sanjeevchopra sanjeevchopra Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frank, explained that this is useful to prevent against dictionary attacks. Lets keep it and add some comments here 👍


private String encryptionKey;

private static final Encryptor INSTANCE = new Encryptor();
Copy link
Contributor

@sanjeevchopra sanjeevchopra Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will work, because the object instance being created here will not be spring managed, and hence not receive the ENCRYPTION_KEY value from the env var. Is there a integration test for this yet ?

  • On 2nd thought the cleanest way to solve this would be to have AttributeConnectorService decrypt the client secret. Since it is spring managed, it can autowire the Encryptor to it. You could do the json serialization/des-ser there too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a commit to make this change.

@sanjeevchopra
Copy link
Contributor

I also pushed a commit with some refactoring on how to handle json serialization/de-ser' . If it looks better - please keep it. Tests are clean with this change.

Also - if you move the ser/de-ser to the service, the refactoring still applies - should be easily portable.

@sanjeevchopra
Copy link
Contributor

This branch is ready to merge, imo.

@sanjeevchopra sanjeevchopra self-assigned this Mar 18, 2017
@sanjeevchopra
Copy link
Contributor

sanjeevchopra commented Mar 18, 2017

PR build passed for predix-cloud - https://predix1.jenkins.build.ge.com/job/Predix-Security/job/ACS/job/ACS-PullRequest/job/acs-integration-pullrequest/291/

(issue seems to be postgres resources - it cannot create 4 db instances at a time. I had to remove some db instances to allow the above build to go through and remove 'cf login' command from the jenkins job)

Filed https://gesoftware.service-now.com/nav_to.do?uri=incident.do?sys_id=3bc1cd164f25f600b3d87acd0210c7d5 for this

Signed-off-by: Sanjeev Chopra <[email protected]>
Signed-off-by: Irina Epshteyn
@sanjeevchopra sanjeevchopra merged commit 8ae555d into develop Mar 19, 2017
@anubhavi25 anubhavi25 deleted the US92112 branch March 21, 2017 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants