/// <summary> /// Derive a new encrypt key from the given decrypt key value. /// </summary> /// /// <param name="keyBits"></param> /// <returns>The new encrypt key (DER-encoded public key).</returns> public static EncryptKey deriveEncryptKey(Blob keyBits) { // Decode the PKCS #8 private key. (We don't use RSAPrivateCrtKey because // the Android library doesn't have an easy way to decode into it.) DerNode parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(keyBits.buf(), 0); IList pkcs8Children = parsedNode.getChildren(); IList algorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(pkcs8Children, 1) .getChildren(); String oidString = ((DerNode.DerOid)algorithmIdChildren[0]) .toVal().toString(); Blob rsaPrivateKeyDer = ((DerNode)pkcs8Children[2]).getPayload(); String RSA_ENCRYPTION_OID = "1.2.840.113549.1.1.1"; if (!oidString.equals(RSA_ENCRYPTION_OID)) { throw new DerDecodingException( "The PKCS #8 private key is not RSA_ENCRYPTION"); } // Decode the PKCS #1 RSAPrivateKey. parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(rsaPrivateKeyDer.buf(), 0); IList rsaPrivateKeyChildren = parsedNode.getChildren(); Blob modulus = ((DerNode)rsaPrivateKeyChildren[1]).getPayload(); Blob publicExponent = ((DerNode)rsaPrivateKeyChildren[2]) .getPayload(); System.SecurityPublicKey publicKey = keyFactory_ .generatePublic(new RSAPublicKeySpec(new Int64(modulus .getImmutableArray()), new Int64(publicExponent .getImmutableArray()))); return(new EncryptKey(new Blob(publicKey.getEncoded(), false))); }
/// <summary> /// Encrypt the plainData using the keyBits according the encrypt params. /// </summary> /// /// <param name="keyBits">The key value (DER-encoded public key).</param> /// <param name="plainData">The data to encrypt.</param> /// <param name="params">This encrypts according to params.getAlgorithmType().</param> /// <returns>The encrypted data.</returns> public static Blob encrypt(Blob keyBits, Blob plainData, EncryptParams paras) { System.SecurityPublicKey publicKey = keyFactory_ .generatePublic(new X509EncodedKeySpec(keyBits .getImmutableArray())); String transformation; if (paras.getAlgorithmType() == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs) { transformation = "RSA/ECB/PKCS1Padding"; } else if (paras.getAlgorithmType() == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep) { transformation = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"; } else { throw new Exception("unsupported padding scheme"); } Cipher cipher = javax.crypto.Cipher.getInstance(transformation); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, publicKey); return(new Blob(cipher.doFinal(plainData.getImmutableArray()), false)); }
initVerify(SecurityPublicKey publicKey) { if (!(publicKey is RsaSecurityPublicKey)) { throw new net.named_data.jndn.util.InvalidKeyException ("Sha256withRsaSecuritySignature.initVerify expects an RsaSecurityPublicKey"); } provider_ = new RSACryptoServiceProvider(); provider_.ImportParameters(((RsaSecurityPublicKey)publicKey).Parameters); memoryStream_ = new MemoryStream(); }
/// <summary> /// Verify the buffer against the signature using the public key. /// </summary> /// /// <param name="buffer">The input buffer to verify.</param> /// <param name="signature">The signature bytes.</param> /// <param name="publicKey">The object containing the public key.</param> /// <param name="digestAlgorithm">The digest algorithm.</param> /// <returns>True if verification succeeds, false if verification fails.</returns> /// <exception cref="System.ArgumentException">for an invalid public key type ordigestAlgorithm.</exception> public static bool verifySignature(ByteBuffer buffer, byte[] signature, PublicKey publicKey, DigestAlgorithm digestAlgorithm) { if (digestAlgorithm == net.named_data.jndn.security.DigestAlgorithm.SHA256) { if (publicKey.getKeyType() == net.named_data.jndn.security.KeyType.RSA) { try { KeyFactory keyFactory = System.KeyFactory.getInstance("RSA"); System.SecurityPublicKey securityPublicKey = keyFactory .generatePublic(new X509EncodedKeySpec(publicKey .getKeyDer().getImmutableArray())); System.SecuritySignature rsaSignature = System.SecuritySignature .getInstance("SHA256withRSA"); rsaSignature.initVerify(securityPublicKey); rsaSignature.update(buffer); return(rsaSignature.verify(signature)); } catch (Exception ex) { return(false); } } else if (publicKey.getKeyType() == net.named_data.jndn.security.KeyType.EC) { try { KeyFactory keyFactory_0 = System.KeyFactory.getInstance("EC"); System.SecurityPublicKey securityPublicKey_1 = keyFactory_0 .generatePublic(new X509EncodedKeySpec(publicKey .getKeyDer().getImmutableArray())); System.SecuritySignature ecdsaSignature = System.SecuritySignature .getInstance("SHA256withECDSA"); ecdsaSignature.initVerify(securityPublicKey_1); ecdsaSignature.update(buffer); return(ecdsaSignature.verify(signature)); } catch (Exception ex_2) { return(false); } } else { throw new ArgumentException( "verifySignature: Invalid key type"); } } else { throw new ArgumentException( "verifySignature: Invalid digest algorithm"); } }
/// <summary> /// Verify the ECDSA signature on the SignedBlob using the given public key. /// </summary> /// /// <param name="signature">The signature bits.</param> /// <param name="signedBlob">the SignedBlob with the signed portion to verify.</param> /// <param name="publicKeyDer">The DER-encoded public key used to verify the signature.</param> /// <returns>true if the signature verifies, false if not.</returns> protected static internal bool verifySha256WithEcdsaSignature(Blob signature, SignedBlob signedBlob, Blob publicKeyDer) { KeyFactory keyFactory = null; try { keyFactory = System.KeyFactory.getInstance("EC"); } catch (Exception exception) { // Don't expect this to happen. throw new SecurityException("EC is not supported: " + exception.Message); } System.SecurityPublicKey publicKey = null; try { publicKey = keyFactory.generatePublic(new X509EncodedKeySpec( publicKeyDer.getImmutableArray())); } catch (InvalidKeySpecException exception_0) { // Don't expect this to happen. throw new SecurityException("X509EncodedKeySpec is not supported: " + exception_0.Message); } System.SecuritySignature ecSignature = null; try { ecSignature = System.SecuritySignature .getInstance("SHA256withECDSA"); } catch (Exception e) { // Don't expect this to happen. throw new SecurityException( "SHA256withECDSA algorithm is not supported"); } try { ecSignature.initVerify(publicKey); } catch (InvalidKeyException exception_1) { throw new SecurityException("InvalidKeyException: " + exception_1.Message); } try { ecSignature.update(signedBlob.signedBuf()); return(ecSignature.verify(signature.getImmutableArray())); } catch (SignatureException exception_2) { throw new SecurityException("SignatureException: " + exception_2.Message); } }
/// <summary> /// Get the encoded public key for this private key. /// </summary> /// /// <returns>The public key encoding Blob.</returns> /// <exception cref="TpmPrivateKey.Error">if no private key is loaded, or errorconverting to a public key.</exception> public Blob derivePublicKey() { if (keyType_ == net.named_data.jndn.security.KeyType.EC) { throw new TpmPrivateKey.Error( "TODO: derivePublicKey for EC is not implemented"); } else if (keyType_ == net.named_data.jndn.security.KeyType.RSA) { // Decode the PKCS #1 RSAPrivateKey. (We don't use RSAPrivateCrtKey because // the Android library doesn't have an easy way to decode into it.) IList rsaPrivateKeyChildren; try { DerNode parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(toPkcs1().buf(), 0); rsaPrivateKeyChildren = parsedNode.getChildren(); } catch (DerDecodingException ex) { throw new TpmPrivateKey.Error("Error parsing RSA PKCS #1 key: " + ex); } Blob modulus = ((DerNode)rsaPrivateKeyChildren[1]) .getPayload(); Blob publicExponent = ((DerNode)rsaPrivateKeyChildren[2]) .getPayload(); try { System.SecurityPublicKey publicKey = System.KeyFactory.getInstance( "RSA").generatePublic( new RSAPublicKeySpec((modulus .getImmutableArray()), ( publicExponent.getImmutableArray()))); return(new Blob(publicKey.getEncoded(), false)); } catch (Exception ex_0) { throw new TpmPrivateKey.Error("Error making RSA public key: " + ex_0); } } else { throw new TpmPrivateKey.Error( "derivePublicKey: The private key is not loaded"); } }
/// <summary> /// Encrypt the plainData using the keyBits according the encrypt algorithm type. /// </summary> /// /// <param name="plainData">The data to encrypt.</param> /// <param name="algorithmType"></param> /// <returns>The encrypted data.</returns> public Blob encrypt(byte[] plainData, EncryptAlgorithmType algorithmType) { System.SecurityPublicKey publicKey = keyFactory_ .generatePublic(new X509EncodedKeySpec(keyDer_ .getImmutableArray())); String transformation; if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs) { if (keyType_ != net.named_data.jndn.security.KeyType.RSA) { throw new Exception("The key type must be RSA"); } transformation = "RSA/ECB/PKCS1Padding"; } else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep) { if (keyType_ != net.named_data.jndn.security.KeyType.RSA) { throw new Exception("The key type must be RSA"); } transformation = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"; } else { throw new Exception("unsupported padding scheme"); } Cipher cipher = javax.crypto.Cipher.getInstance(transformation); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, publicKey); return(new Blob(cipher.doFinal(plainData), false)); }
initVerify(SecurityPublicKey publicKey);
public KeyPair(SecurityPublicKey publicKey, PrivateKey privateKey) { publicKey_ = publicKey; privateKey_ = privateKey; }