/// <summary> /// Make a CK Data packet for ckName_ encrypted by the KEK in kekData_ and /// insert it in the storage_. /// </summary> /// /// <param name="onError_0">error string.</param> /// <returns>True on success, else false.</returns> internal bool makeAndPublishCkData(net.named_data.jndn.encrypt.EncryptError.OnError onError_0) { try { PublicKey kek = new PublicKey(kekData_.getContent()); EncryptedContent content = new EncryptedContent(); content.setPayload(kek.encrypt(ckBits_, net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep)); Data ckData = new Data(new Name(ckName_).append( NAME_COMPONENT_ENCRYPTED_BY).append(kekData_.getName())); ckData.setContent(content.wireEncodeV2()); // FreshnessPeriod can serve as a soft access control for revoking access. ckData.getMetaInfo().setFreshnessPeriod( DEFAULT_CK_FRESHNESS_PERIOD_MS); keyChain_.sign(ckData, ckDataSigningInfo_); storage_.insert(ckData); logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "Publishing CK data: {0}", ckData.getName()); return(true); } catch (Exception ex) { onError_0.onError(net.named_data.jndn.encrypt.EncryptError.ErrorCode.EncryptionFailure, "Failed to encrypt generated CK with KEK " + kekData_.getName().toUri()); return(false); } }
/// <summary> /// Encrypt the plainData using the existing Content Key (CK) and return a new /// EncryptedContent. /// </summary> /// /// <param name="plainData">The data to encrypt.</param> /// <returns>The new EncryptedContent.</returns> public EncryptedContent encrypt(byte[] plainData) { // Generate the initial vector. byte[] initialVector = new byte[AES_IV_SIZE]; net.named_data.jndn.util.Common.getRandom().nextBytes(initialVector); Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5PADDING"); try { cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, new SecretKeySpec(ckBits_, "AES"), new IvParameterSpec(initialVector)); } catch (InvalidKeyException ex) { throw new Exception( "If the error is 'Illegal key size', try installing the " + "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files: " + ex); } byte[] encryptedData = cipher.doFinal(plainData); EncryptedContent content = new EncryptedContent(); content.setInitialVector(new Blob(initialVector, false)); content.setPayload(new Blob(encryptedData, false)); content.setKeyLocatorName(ckName_); return(content); }
/// <summary> /// Authorize a member identified by memberCertificate to decrypt data under /// the policy. /// </summary> /// /// <param name="memberCertificate"></param> /// <returns>The published KDK Data packet.</returns> public Data addMember(CertificateV2 memberCertificate) { Name kdkName = new Name(nacKey_.getIdentityName()); kdkName.append(net.named_data.jndn.encrypt.EncryptorV2.NAME_COMPONENT_KDK) .append(nacKey_.getName().get(-1)) // key-id .append(net.named_data.jndn.encrypt.EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY) .append(memberCertificate.getKeyName()); int secretLength = 32; byte[] secret = new byte[secretLength]; net.named_data.jndn.util.Common.getRandom().nextBytes(secret); // To be compatible with OpenSSL which uses a null-terminated string, // replace each 0 with 1. And to be compatible with the Java security // library which interprets the secret as a char array converted to UTF8, // limit each byte to the ASCII range 1 to 127. for (int i = 0; i < secretLength; ++i) { if (secret[i] == 0) { secret[i] = 1; } secret[i] &= 0x7f; } SafeBag kdkSafeBag = keyChain_.exportSafeBag( nacKey_.getDefaultCertificate(), ILOG.J2CsMapping.NIO.ByteBuffer.wrap(secret)); PublicKey memberKey = new PublicKey(memberCertificate.getPublicKey()); EncryptedContent encryptedContent = new EncryptedContent(); encryptedContent.setPayload(kdkSafeBag.wireEncode()); encryptedContent.setPayloadKey(memberKey.encrypt(secret, net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep)); Data kdkData = new Data(kdkName); kdkData.setContent(encryptedContent.wireEncodeV2()); // FreshnessPeriod can serve as a soft access control for revoking access. kdkData.getMetaInfo().setFreshnessPeriod( DEFAULT_KDK_FRESHNESS_PERIOD_MS); keyChain_.sign(kdkData, new SigningInfo(identity_)); storage_.insert(kdkData); return(kdkData); }
/// <summary> /// Encrypt the payload using the symmetric key according to params, and return /// an EncryptedContent. /// </summary> /// /// <param name="payload">The data to encrypt.</param> /// <param name="key">The key value.</param> /// <param name="keyName">The key name for the EncryptedContent key locator.</param> /// <param name="params">The parameters for encryption.</param> /// <returns>A new EncryptedContent.</returns> private static EncryptedContent encryptSymmetric(Blob payload, Blob key, Name keyName, EncryptParams paras) { EncryptAlgorithmType algorithmType = paras.getAlgorithmType(); Blob initialVector = paras.getInitialVector(); KeyLocator keyLocator = new KeyLocator(); keyLocator.setType(net.named_data.jndn.KeyLocatorType.KEYNAME); keyLocator.setKeyName(keyName); if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc || algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb) { if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc) { if (initialVector.size() != net.named_data.jndn.encrypt.algo.AesAlgorithm.BLOCK_SIZE) throw new Exception("incorrect initial vector size"); } Blob encryptedPayload = net.named_data.jndn.encrypt.algo.AesAlgorithm.encrypt(key, payload, paras); EncryptedContent result = new EncryptedContent(); result.setAlgorithmType(algorithmType); result.setKeyLocator(keyLocator); result.setPayload(encryptedPayload); result.setInitialVector(initialVector); return result; } else throw new Exception("Unsupported encryption method"); }
/// <summary> /// Encrypt the payload using the asymmetric key according to params, and /// return an EncryptedContent. /// </summary> /// /// <param name="payload"></param> /// <param name="key">The key value.</param> /// <param name="keyName">The key name for the EncryptedContent key locator.</param> /// <param name="params">The parameters for encryption.</param> /// <returns>A new EncryptedContent.</returns> private static EncryptedContent encryptAsymmetric(Blob payload, Blob key, Name keyName, EncryptParams paras) { EncryptAlgorithmType algorithmType = paras.getAlgorithmType(); KeyLocator keyLocator = new KeyLocator(); keyLocator.setType(net.named_data.jndn.KeyLocatorType.KEYNAME); keyLocator.setKeyName(keyName); if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs || algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep) { Blob encryptedPayload = net.named_data.jndn.encrypt.algo.RsaAlgorithm.encrypt(key, payload, paras); EncryptedContent result = new EncryptedContent(); result.setAlgorithmType(algorithmType); result.setKeyLocator(keyLocator); result.setPayload(encryptedPayload); return result; } else throw new Exception("Unsupported encryption method"); }
/// <summary> /// Decode input as a EncryptedContent in NDN-TLV and set the fields of the /// encryptedContent object. /// </summary> /// /// <param name="encryptedContent"></param> /// <param name="input"></param> /// <param name="copy">unchanged while the Blob values are used.</param> /// <exception cref="EncodingException">For invalid encoding</exception> public override void decodeEncryptedContent(EncryptedContent encryptedContent, ByteBuffer input, bool copy) { TlvDecoder decoder = new TlvDecoder(input); int endOffset = decoder .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptedContent); Tlv0_2WireFormat.decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, encryptedContent.getKeyLocator(), decoder, copy); int algorithmType = (int) decoder .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptionAlgorithm); if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb.getNumericType()) encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb); else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc.getNumericType()) encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc); else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs.getNumericType()) encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs); else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep.getNumericType()) encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep); else throw new EncodingException( "Unrecognized EncryptionAlgorithm code " + algorithmType); encryptedContent.setInitialVector(new Blob(decoder.readOptionalBlobTlv( net.named_data.jndn.encoding.tlv.Tlv.Encrypt_InitialVector, endOffset), copy)); encryptedContent.setPayload(new Blob(decoder .readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptedPayload), copy)); decoder.finishNestedTlvs(endOffset); }
public void testSetterGetter() { EncryptedContent content = new EncryptedContent(); Assert.AssertEquals(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.NONE, content.getAlgorithmType()); Assert.AssertEquals(true, content.getPayload().isNull()); Assert.AssertEquals(true, content.getInitialVector().isNull()); Assert.AssertEquals(net.named_data.jndn.KeyLocatorType.NONE, content.getKeyLocator().getType()); content.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep); Assert.AssertEquals(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep, content.getAlgorithmType()); Assert.AssertEquals(true, content.getPayload().isNull()); Assert.AssertEquals(true, content.getInitialVector().isNull()); Assert.AssertEquals(net.named_data.jndn.KeyLocatorType.NONE, content.getKeyLocator().getType()); KeyLocator keyLocator = new KeyLocator(); keyLocator.setType(net.named_data.jndn.KeyLocatorType.KEYNAME); keyLocator.getKeyName().set("/test/key/locator"); content.setKeyLocator(keyLocator); Assert.AssertTrue(content.getKeyLocator().getType() != net.named_data.jndn.KeyLocatorType.NONE); Assert.AssertTrue(content.getKeyLocator().getKeyName() .equals(new Name("/test/key/locator"))); Assert.AssertEquals(true, content.getPayload().isNull()); Assert.AssertEquals(true, content.getInitialVector().isNull()); content.setPayload(new Blob(message, false)); Assert.AssertTrue(content.getPayload().equals(new Blob(message, false))); content.setInitialVector(new Blob(iv, false)); Assert.AssertTrue(content.getInitialVector().equals(new Blob(iv, false))); Blob encoded = content.wireEncode(); Blob contentBlob = new Blob(encrypted, false); Assert.AssertTrue(contentBlob.equals(encoded)); }