Personnalisation du cryptage des montages Azure Blob Storage
Cette rubrique décrit la procédure de personnalisation du cryptage pour le stockage de contenu crypté sur Azure Blob Storage. En standard, le contenu stocké sur Azure Blob Storage est crypté à l'aide du type de cryptage serverSideEncryption. Le contenu stocké dans les coffres-forts basés sur un système de fichiers présente un format brut.
Windchill prend en charge les types de cryptages suivants :
1. Côté serveur : vous pouvez choisir entre deux options :
a. Clé gérée par Azure : il s'agit du type de cryptage par défaut automatiquement défini par le système Azure.
b. Clé gérée par Azure Key Vault : vous pouvez définir la clé Key Vault pour un conteneur à partir du Portail Azure.
2. Côté client : vous pouvez choisir entre deux options :
a. clientSideEncryption-keyvault : ce type de cryptage utilise les clés gérées par Azure Key Vault.
b. clientSideEncryption : ce type de cryptage utilise les clés gérées par le client.
Les détails des implémentations de délégué pour le cryptage côté client sont fournis à la section "Ecriture d'implémentations de délégué pour le cryptage côté client".
|
La gestion des options de cryptage incombe à l'utilisateur. Vous devez vous assurer que le contenu reste accessible en cas de modification des options de cryptage.
|
Ecriture d'implémentations de délégué pour le cryptage côté client
Pour personnaliser le cryptage du contenu sur Azure Blob Storage, écrivez les implémentations de délégué suivantes :
1. Délégué de configuration du cryptage Blob : le délégué par défaut est
com.ptc.windchill.objectstorage.azureblob.encryption.DefaultBlobEncryptConfigurator. Le délégué par défaut renvoie le type de cryptage
serverSideEncryption. Si vous souhaitez utiliser un autre type de cryptage, écrivez un délégué qui renvoie le type de cryptage attendu, déployez les fichiers de classe et effectuez la configuration à l'aide de l'outil en ligne de commande. Pour plus d'informations sur la configuration, consultez la section
Configuration des coffres-forts Windchill pour l'utilisation d'Azure Blobs.
Vous trouverez ci-après un exemple de délégué.
SampleBlobEncryptConfigurator.java :
package com.abc.windchill.objectstorage.azureblob.encryption;
import com.ptc.windchill.objectstorage.azureblob.exception.BlobException;
public class SampleBlobEncryptConfigurator implements BlobEncryptConfigurator {
private static final String CSE_KEYVAULT_FOLDER = "keyvault";
private static final String CSE_FOLDER = "cse";
@Override
public String getBlobEncryptionType(String storageAccountName, String containerName, String blobName) throws BlobException {
if (blobName != null && blobName.contains(CSE_KEYVAULT_FOLDER)) {
return BlobEncryptionType.CSE_KEYVAULT;
} else if (blobName != null && blobName.contains(CSE_FOLDER)) {
return BlobEncryptionType.CSE;
} else {
return BlobEncryptionType.SSE;
}
}
}
Selon le chemin de montage (nom de l'objet blob), le délégué SampleBlobEncryptConfigurator renvoie le type de cryptage serverSideEncryption, clientSideEncryption ou clientSideEncryption-keyvault. Le contenu stocké sur Azure Blob Storage est crypté à l'aide de ces types de cryptages. L'API getBlobEncryptionType reçoit le nom du compte de stockage, le nom du conteneur et le nom de l'objet blob en tant qu'argument. Vous pouvez programmer le type de cryptage en utilisant le nom du compte de stockage, le nom du conteneur et le nom de l'objet blob. Par exemple, pour le conteneur c1, renvoyez le type de cryptage serverSideEncryption, et pour le conteneur c2, renvoyez le type de cryptage clientSideEncryption-keyvault.
Les valeurs de type de cryptage possibles sont les suivantes :
a. serverSideEncryption : le contenu est stocké à l'aide du cryptage côté serveur avec des clés gérées par Azure.
b. clientSideEncryption-keyvault : le contenu est stocké à l'aide du cryptage côté client avec des clés gérées par Azure Key Vault.
c. clientSideEncryption : le contenu est stocké à l'aide du cryptage côté client avec des clés fournies par le client.
2. CSEKeyVaultKeyProvider Delegate : ce délégué s'applique si le type de cryptage est configuré comme étant
clientSideEncryption-keyvault. Il n'existe aucune implémentation par défaut pour ce délégué. Vous devez écrire un délégué qui renvoie les paramètres de connexion Azure Key Vault attendus, déployer les fichiers de classe et effectuer la configuration à l'aide de l'outil en ligne de commande. Pour plus d'informations sur la configuration, consultez la section
Configuration des coffres-forts Windchill pour l'utilisation d'Azure Blobs.
|
N'utilisez pas les exemples d'implémentations ci-après tels quels dans un environnement de production.
|
Vous trouverez ci-après un exemple de délégué :
SampleCSEKeyVaultKeyProvider.java : cet exemple d'implémentation illustre la façon dont vous pouvez renvoyer les paramètres de connexion Azure Key Vault. Pour plus d'informations sur l'enregistrement d'un coffre de clés et d'une application, consultez la section "Définition du cryptage Key Vault dans Azure Blob" de la rubrique
Configuration des coffres-forts Windchill pour l'utilisation d'Azure Blobs.
package com.abc.windchill.objectstorage.azureblob.encryption.csekeyvault;
import com.ptc.windchill.objectstorage.azureblob.encryption.csekeyvault.CSEKeyVaultKeyProvider;
import com.ptc.windchill.objectstorage.azureblob.encryption.csekeyvault.KeyVaultConnectionParams;
import com.ptc.windchill.objectstorage.azureblob.exception.BlobException;
/**
* Sample implementation of CSEKeyVaultKeyProvider.
*/
public class SampleCSEKeyVaultKeyProvider implements CSEKeyVaultKeyProvider {
@Override
public KeyVaultConnectionParams getKeyVaultConnectionDetails(String containerName, String blobName)
throws BlobException {
String keyVaultKeyIdUrl = "https://mykeyvault.vault.azure.net/keys/MyKeyVaultKey";
String appId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
String appAuthKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
KeyVaultConnectionParams connectionParams = new KeyVaultConnectionParams(keyVaultKeyIdUrl, appId,
appAuthKey);
return connectionParams;
}
}
3. CSESecKeyGenerator Delegate : si vous configurez le type de cryptage comme étant
clientSideEncryption, vous devez écrire l'implémentation pour ce délégué, puis configurer le délégué. Ce délégué ne s'applique que si le type de cryptage est configuré comme étant
clientSideEncryption. Il n'existe aucune implémentation par défaut pour ce délégué. Ecrivez un délégué qui gère les éléments
KeyPair et
KeyId, déployez les fichiers de classe et effectuez la configuration à l'aide de l'outil en ligne de commande. Pour plus d'informations sur la configuration, consultez la section
Configuration des coffres-forts Windchill pour l'utilisation d'Azure Blobs.
Vous trouverez ci-après un exemple de délégué :
SampleCSESecKeyGenerator.java : cet exemple d'implémentation indique comment générer des éléments KeyPair et KeyId. Cet exemple d'implémentation recherche un élément KeyPair existant. S'il trouve l'élément KeyPair, il le renvoie. Dans le cas contraire, il génère un nouvel élément KeyPair, le stocke dans un fichier sur disque, puis le renvoie. Vous pouvez choisir la stratégie de sécurisation du stockage de l'élément KeyPair. En outre, cet exemple d'implémentation utilise un seul élément KeyPair pour tous les fichiers du coffre-fort. Vous pouvez écrire votre propre algorithme en vue de gérer plusieurs éléments KeyPair pour les conteneurs ou les objets blob stockés dans Azure.
package com.abc.windchill.objectstorage.azureblob.encryption.cse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import com.ptc.windchill.objectstorage.azureblob.encryption.cse.CSESecKeyGenerator;
import com.ptc.windchill.objectstorage.azureblob.exception.BlobException;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.wrmf.delivery.ObjectIS;
import wt.wrmf.delivery.PayloadShippingItem;
import wt.wrmf.delivery.ShippingHelper;
/**
* Sample implementation of CSESecKeyGenerator.
*/
public class SampleCSESecKeyGenerator implements CSESecKeyGenerator {
private File keyPairFile;
public static String keyPairFileName;
static {
try {
WTProperties props = WTProperties.getLocalProperties();
String windchillHome = props.getProperty("wt.home");
keyPairFileName = windchillHome + File.separator + "RsaKey";
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
@Override
public KeyPair getKeyPair(String storageAccountName, String containerName, String blobName) throws BlobException {
try{
KeyPair wrapKey = getKeyPairFromFileStore();
if(wrapKey == null){
// Create the IKey used for encryption.
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
wrapKey = keyGen.generateKeyPair();
storeKeyPairInFileStore(containerName, blobName, wrapKey);
storeKeyPairInFileStoreOnReplica(containerName, blobName, wrapKey);
}
return wrapKey;
}
catch(Exception e){
throw new BlobException(e);
}
}
@Override
public String getKeyId(String storageAccountName, String containerName, String blobName) throws BlobException {
return containerName;//using container name as key id
}
private KeyPair getKeyPairFromFileStore()throws IOException, ClassNotFoundException{
KeyPair keyPair = null;
File keyPairFile = getKeyPairFile();
try(
FileInputStream fis = new FileInputStream(keyPairFile);
ObjectInputStream ois = new ObjectInputStream(fis);){
keyPair = (KeyPair)ois.readObject();
}catch (IOException ignore){
ignore.printStackTrace();
}
return keyPair;
}
public synchronized void storeKeyPairInFileStore(String containerName, String blobName, KeyPair keyPair)throws IOException{
File keyPairFile = getKeyPairFile();
try(FileOutputStream fos = new FileOutputStream(keyPairFile, true);
ObjectOutputStream oos = new ObjectOutputStream(fos);){
oos.writeObject(keyPair);
oos.flush();
}
}
private synchronized void storeKeyPairInFileStoreOnReplica(String containerName, String blobName, KeyPair keyPair)
throws Exception {
//this is a private method that invokes method call on replica site
invokeMethodOnReplica(getReplicaSite(),
SampleCSESecKeyGenerator.class.getName(), "setKeyPairOnReplica",
new String[] { String.class.getName(), String.class.getName(), KeyPair.class.getName() },
new Serializable[] { containerName, blobName, keyPair });
}
private synchronized File getKeyPairFile() throws IOException {
if (keyPairFile == null) {
keyPairFile = new File(keyPairFileName);
if (!keyPairFile.exists()) {
keyPairFile.createNewFile();
}
}
return keyPairFile;
}
@Override
public boolean removeKeyPair(String storageAccountName, String containerName, String blobName) {
return true;//do not remove the KeyPair, since sample code uses single KeyPair for all files in vault.
}
public static PayloadShippingItem setKeyPairOnReplica(String storageAccountName,
String containerName, String blobName, KeyPair keyPair) throws WTException {
PayloadShippingItem psi = ShippingHelper.service.createPayloadShippingItem();
try {
File keyPairFile = new File(keyPairFileName);
if (!keyPairFile.exists()) {
keyPairFile.createNewFile();
}
try (FileOutputStream fos = new FileOutputStream(keyPairFile, false);
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(keyPair);
oos.flush();
}
Object[] valuesToReturn = new Object[] {};
ObjectIS retValsIS = new ObjectIS(valuesToReturn);
psi.setPayload(retValsIS);
} catch (Exception e) {
throw new WTException(e);
}
return psi;
}
}
Gestion du type de cryptage
Si vous souhaitez modifier le type de cryptage d'un coffre-fort, procédez comme suit :
1. Créez un coffre-fort et configurez-le avec le type de cryptage souhaité en utilisant une implémentation de délégué. Pour plus d'informations, reportez-vous à la section "Ecriture d'implémentations de délégué pour le cryptage côté client".
2. Mettez à jour la règle de stockage afin de diriger le contenu vers le nouveau coffre-fort.
3. Exécutez la planification de réaffectation de coffre-fort.