public static SymmetricAlgorithm CreateSymAlgorithm(SymAlgorithms saAlgo) { SymmetricAlgorithm saReturn; switch (saAlgo) { case SymAlgorithms.AES128: saReturn = Rijndael.Create(); saReturn.BlockSize = 128; saReturn.KeySize = 128; break; case SymAlgorithms.AES192: saReturn = Rijndael.Create(); saReturn.BlockSize = 128; saReturn.KeySize = 192; break; case SymAlgorithms.AES256: saReturn = Rijndael.Create(); saReturn.BlockSize = 128; saReturn.KeySize = 256; break; case SymAlgorithms.CAST5: saReturn = CAST5.Create(); break; case SymAlgorithms.Triple_DES: saReturn = TripleDES.Create(); break; default: throw new System.Security.Cryptography.CryptographicException("The algorithm is not supported!"); } return(saReturn); }
public BigInteger[] GetDecryptedKeyMaterial(string strPassphrase) { BigInteger[] biKeys = new BigInteger[0]; if (this.bIsEncrypted) { SharpPrivacy.SharpPrivacyLib.Cipher.SymmetricAlgorithm saAlgo; switch (this.SymmetricalAlgorithm) { case SymAlgorithms.AES128: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 128; break; case SymAlgorithms.AES192: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 192; break; case SymAlgorithms.AES256: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 256; break; case SymAlgorithms.Triple_DES: saAlgo = TripleDES.Create(); saAlgo.KeySize = 192; break; case SymAlgorithms.CAST5: saAlgo = CAST5.Create(); break; default: throw(new System.NotSupportedException("Sorry, but the Algorithm that was used to encrypt the secret key data is not (yet) supported by SharpPrivacy!")); } saAlgo.Mode = CipherMode.CFB; saAlgo.Key = this.S2KSpecifier.GetKey(strPassphrase, saAlgo.KeySize); if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v3) { throw(new System.NotImplementedException("Sorry, but we have not yet implemented the decryption of v3 keys!")); } else if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v4) { //In v4 keys, everything - including mpi headers and checksum //is encrypted. Should be a heck of a lot easier than for //v3 keys. saAlgo.IV = this.InitialVector; saAlgo.Padding = PaddingMode.None; byte[] bOutput = new byte[this.bEncryptedKeyMaterial.Length]; ICryptoTransform ictDec = saAlgo.CreateDecryptor(); ictDec.TransformBlock(bEncryptedKeyMaterial, 0, bEncryptedKeyMaterial.Length, ref bOutput, 0); int iCurrentChecksum = 0; for (int i = 0; i < bOutput.Length; i++) { iCurrentChecksum = (iCurrentChecksum + bOutput[i]) % 65536; } if (pkpPublicKey.Algorithm == AsymAlgorithms.DSA || pkpPublicKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign || pkpPublicKey.Algorithm == AsymAlgorithms.ElGamal_Encrypt_Only) { biKeys = new BigInteger[1]; try { biKeys = BigInteger.ParseMPIs(bOutput, 1); } catch (Exception) { throw new Exception("Invalid Passphrase!"); } } else if (pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Only || pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign || pkpPublicKey.Algorithm == AsymAlgorithms.RSA_Sign_Only) { biKeys = new BigInteger[4]; try { biKeys = BigInteger.ParseMPIs(bOutput, 4); } catch (Exception) { throw new Exception("Invalid Passphrase!"); } } } } else { //Key Material is not encrypted anyway biKeys = this.DecryptedKeyMaterial; } return(biKeys); }
public void EncryptKeyMaterial(BigInteger[] biGivenKeyMaterial, string strPassphrase) { this.biDecryptedKeyMaterial = biGivenKeyMaterial; if (!bIsEncrypted) { return; } if (this.PublicKey.Version == PublicKeyPacketVersionNumbers.v4) { int iKeyMaterialLength = 0; for (int i = 0; i < this.biDecryptedKeyMaterial.Length; i++) { iKeyMaterialLength += biDecryptedKeyMaterial[i].GetMPI().Length; } byte[] bData = new byte[iKeyMaterialLength + 2]; int iPos = 0; for (int i = 0; i < this.biDecryptedKeyMaterial.Length; i++) { byte[] bMPI = biDecryptedKeyMaterial[i].GetMPI(); Array.Copy(bMPI, 0, bData, iPos, bMPI.Length); iPos += bMPI.Length; } int iChecksum = 0; for (int i = 0; i < bData.Length - 2; i++) { iChecksum = (iChecksum + bData[i]) % 65536; } bData[iPos++] = (byte)((iChecksum >> 8) & 0xFF); bData[iPos++] = (byte)(iChecksum & 0xFF); SharpPrivacy.SharpPrivacyLib.Cipher.SymmetricAlgorithm saAlgo; switch (this.SymmetricalAlgorithm) { case SymAlgorithms.AES128: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 128; break; case SymAlgorithms.AES192: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 192; break; case SymAlgorithms.AES256: saAlgo = Rijndael.Create(); saAlgo.BlockSize = 128; saAlgo.KeySize = 256; break; case SymAlgorithms.Triple_DES: saAlgo = TripleDES.Create(); saAlgo.KeySize = 192; break; case SymAlgorithms.CAST5: saAlgo = CAST5.Create(); break; default: throw(new System.NotSupportedException("Sorry, but the Algorithm that was used to encrypt the secret key data is not (yet) supported by SharpPrivacy!")); } saAlgo.Mode = CipherMode.CFB; saAlgo.Key = this.S2KSpecifier.GetKey(strPassphrase, saAlgo.KeySize); saAlgo.IV = this.InitialVector; saAlgo.Padding = PaddingMode.None; byte[] bOutput = new byte[bData.Length]; ICryptoTransform ictEnc = saAlgo.CreateEncryptor(); ictEnc.TransformBlock(bData, 0, bData.Length, ref bOutput, 0); byte[] bTmp = new byte[bData.Length]; Array.Copy(bOutput, 0, bTmp, 0, bTmp.Length); bOutput = bTmp; if (bOutput.Length != bData.Length) { throw new Exception("Encryption of the secret Key material did not work correctly. Look at the file SecretKeyPacket, function EncryptKeyMaterial()"); } bEncryptedKeyMaterial = bOutput; } else { throw new Exception("Sorry, but we don't support v3 secret keys so far!"); } this.bIsUpdated = true; }