Algoritmo de criptografia RSA
Vamos revisar o algoritmo de criptografia da RSA. Utilizamos linguagem relativamente padronizada para descrever esse algoritmo com base na definição de algoritmo de criptografia de chave pública e algoritmo de assinatura.
O sistema de criptografia de chave pública da RSA inclui os seguintes 3 algoritmos: keygen (algoritmo de geração de chaves), criptografia (criptografia) e descriptografar (algoritmo de descriptografia).
O algoritmo de geração de chaves usa uma constante de segurança como entrada para produzir uma chave pública PK e uma chave privada SK. A constante de segurança é usada para determinar o quão seguro é o algoritmo de criptografia, que geralmente está relacionado ao tamanho do número Prime P usado pelo algoritmo de criptografia. Quanto maior o número principal P, maior o sistema, garantindo maior segurança. Na RSA, o algoritmo de geração de chaves é o seguinte: o algoritmo primeiro gera aleatoriamente dois números primários grandes diferentes P e Q e calcula n = PQ. Em seguida, o algoritmo calcula a função Euler. Em seguida, o algoritmo seleciona aleatoriamente um número inteiro menor que E e calcula o elemento inverso do módulo d de e. Finalmente, a chave pública é pk = (n, e) e a chave privada é sk = (n, d).
O algoritmo de criptografia usa a chave pública PK e a mensagem M para ser criptografada como entrada e produz o CipherText CT. Na RSA, o algoritmo de criptografia é o seguinte: O algoritmo gera diretamente o texto cifrado, pois o algoritmo de descriptografia usa a chave privada SK e o CipherText CT como as entradas e produz a mensagem M. Como E e D são inversamente opostos um do outro, temos:
Portanto, a partir da descrição do algoritmo, também podemos ver que a chave pública é usada para criptografar os dados e a chave privada é usada para descriptografar os dados. Obviamente, isso também pode ser entendido intuitivamente: uma chave pública é uma chave pública e somente quando é divulgada, todos podem usá -la para criptografar dados. Uma chave privada é uma chave privada, e quem tiver essa chave pode descriptografar o texto cifrado. Caso contrário, se todos puderem ver a chave privada e descriptografá -la, será uma bagunça.
Vamos dar uma olhada na simples implementação em Java:
pacote com.stone.security; importar java.security.Keypair; importar java.security.KeypairGenerator; importar java.security.privateKey; importar java.security.publickey; importar java.util.arrays; importar javax.crypto.cipher; / *** RSA Algoritmo Public Key Criptografia Criptografia assimétrica*/ public class RSA {public static final string key_algorithm = "rsa"; public static final string cipher_algorithm_ecb1 = "rsa/ecb/pkcs1padding"; public static final string cipher_algorithm_ecb2 = "rsa/ecb/oaepwithsha-1andmgf1padding"; // Você não pode usar a string final da Static Public Cipher_algorithm_ecb3 = "oaepwithsha-256andmgf1padding"; // Você não pode usar o PublicKey estático PublicKey; estático privatekey privateKey; cifra estática cifra; Tecl de teclado estático; public static void main(String[] args) throws Exception { method1("Skoda U*(Sfsad7f()*^%%$"); method2("Skoda U*(Sfsad7f()*^%%$"); method3("Skoda U*(Sfsad7f()*^%%$"); } /** * Public key encryption, private key decryption uses the Cipher_algorithm_ecb1 * @param str * @THOURS Exceção */ Método estático 1 (String str) lança exceção {keypairGenerator keyGenerator = keypairGenerator.getInsic (key_algorithM); KeyPair.getPrivate (); Arrays.ToString (Encrypt)); Cipher_algorithm_ecb1 * @param str * @throws Exception */ static void Method2 (String str) lança exceção {keyyairGenerator keyGenerator = keypairGenerator.getInstance (key_algorithm); Keypair Keypair = KeyGenerator.GeraReKeyypair (); PublicKey = Kyypair.getPublic (); privateKey = keypair.getprivate (); cipher = cipher.getInstance (key_algorithm); cipher.init (cipher.encrypt_mode, privateKey); // byte de criptografia de chave privada [] Encrypt = cipher.dofinal (str.getBytes ()); System.out.println ("Criptografia de chave privada 2:" + Arrays.toString (Encrypt)); cipher.init (cipher.decrypt_mode, publicKey); // Public Key Decrypt Byte [] descriptografando = cifra.Dofinal (criptografia); System.out.println ("Public Key descriptografar 2:" + nova string (descriptografar)); }/** * Criptografia de chave privada, a decripção pública -chave usa cipher_algorithm_ecb1 = rsa/ecb/pkcs1padding * @param str * @throws exceção */static void 3 (string str) lança excepção {KeyPairGenerator = KeyPaperMator.GeRator.GeRArator. Keypair Keypair = KeyGenerator.GeraReKeyypair (); PublicKey = Kyypair.getPublic (); privateKey = keypair.getprivate (); cipher = cipher.getInstance (cipher_algorithm_ecb1); cipher.init (cipher.encrypt_mode, privateKey); // byte de criptografia de chave privada [] Encrypt = cipher.dofinal (str.getBytes ()); System.out.println ("Criptografia de chave privada 3:" + Arrays.toString (Encrypt)); cipher.init (cipher.decrypt_mode, publicKey); // byte de descriptografia de chave pública [] descriptografando = cipher.dofinal (criptografia); System.out.println ("3 após descriptografia de chave pública:" + nova string (descriptografar)); }} Algoritmo DSA e assinatura digital
O DSA é geralmente usado para assinaturas digitais e certificação.
O DSA é uma variante dos algoritmos de assinatura Schnorr e Elgamal e é usado pelo NIST nos Estados Unidos como DSS (padrão de assinatura digital).
O DSA é baseado no domínio inteiro de domínio finito discreto logarítmico, e sua segurança é semelhante à RSA.
Na assinatura e autenticação digital da DSA, o remetente usa sua própria chave privada para assinar um arquivo ou mensagem, e o destinatário usa a chave pública do remetente para verificar a autenticidade da assinatura após receber a mensagem. O DSA é apenas um algoritmo, e a diferença entre RSA é que ele não pode ser usado para criptografia e descriptografia, nem para troca de chaves.
Apenas para assinaturas, é muito mais rápido que o RSA.
pacote com.stone.security; importar java.security.key; importar java.security.keyFactory; importar java.security.Keypair; importar java.security.KeypairGenerator; importar java.security.privateKey; importar java.security.publickey; importar java.Security.SecureRandom; importar java.security.signature; importar java.security.spec.pkcs8encodedkeyspec; importar java.security.spec.x509EncodedKeyspec; importar java.util.hashmap; importar java.util.map; importar sun.misc.base64decoder; importar sun.misc.base64Encoder; /*** O algoritmo de assinatura DSA-digital é uma variante dos algoritmos de Schnorr e Elgamal Signature e é usado como DSS pelo NIST nos Estados Unidos. * Em suma, este é um método de verificação mais avançado usado como assinatura digital. Não apenas chaves públicas e privadas, mas também assinaturas digitais. A criptografia de chave privada gera assinaturas digitais, dados de verificação de chave pública e assinaturas. * Se os dados e a assinatura não corresponderem, a verificação será considerada falhada! Ou seja, os dados na transmissão não podem mais ser criptografados. Depois que o receptor obtém os dados, ele recebe a chave pública e a assinatura para verificar se os dados são válidos. */ Public class DSA {/ ***Não apenas você pode usar o algoritmo DSA, mas também pode usar o algoritmo RSA para assinaturas digitais*/ public static string key_algorithm = "rsa"; public static final string assinatura_algorithm = "md5withrsa";*/ public static final string key_algorithm = "dsa"; public static final string assinatura_algorithm = "dsa"; public static final string default_seed = "$%^*%^() (hjg8awfjas7"; // semente padrão public static final string public_key = "dsapublickey"; public static string string_key_key = "strivateKeyKey"; public static void main ([] args) throws {strats strat = "strivateKey"; public static void main (! Você*() _ + "; byte [] data = str.getBytes (); map <string, objeto> keyMap = initKey (); // construir chave publicKey PublicKey = (publicKey) keyMap.get (public_key); privateKeyKey = privateKey (privateKey) keyMap.get: sytkey; System.out.println ("Formato público:" + publicKey.getFormat ()); verify1); } / *** Gere a tecla** @param Seed Seed* @return @objeto* @throws Exceção* / public static map <string, object> initKey (string semente) lança a exceção {System.out.println ("Gereate key"); KeypairGenerator keygen = keypairGenerator.getInstance (key_algorithm); SecureRandom SecureRandom = new SecureRandom (); seculerandom.setSeed (SEED.GETBYTES ()); // O tamanho do módulo deve variar de 512 a 1024 e ser um múltiplo de 64 keygen.initialize (640, SecureRandom); Keypair chaves = keygen.genkeypair (); PrivateKey privateKey = keys.getprivate (); PublicKey PublicKey = Keys.getPublic (); Mapa <string, objeto> map = new Hashmap <string, object> (2); map.put (public_key, publicKey); map.put (private_key, privateKey); mapa de retorno; } / *** Gere a tecla padrão** @return icor objeto* @throws Exception* / public static map <string, object> initKey () lança a exceção {return initKey (default_seed); } / ** * Obtenha a chave privada * * @param keymap * @return * @throws Exception * / public static string getPrivateKey (map <string, object> keymap) lança exceção {key key = (key) keyMap.get (private_key); retornar EncryptBase64 (key.getEncoded ()); // BASE64 CHAVE DE CRIPTIÇÃO PRIVADA}/** * Obtenha a chave pública * * @param keymap * @return * @throws exceção */public static string getpublickey (map <string, object> keymap) lança exceção {key key = (key) keymap.get (public_key); retornar EncryptBase64 (key.getEncoded ()); // BASE64 CRYPTION Public Key}/** * Use a chave privada para assinar digitalmente as informações * @param dados dados criptografados * @Param PrivateKey Private Key - base64 criptografado * @return * @THOLS Excepção */Public Static Sign (Byte [] Data, stringkey) a exceção {Sistema); byte [] keybytes = decryptBase64 (privateKey); PKCS8ENCODEDKEYSPEC KEYSPEC = novo PKCS8ENCODEDKEYSPEC (KeyBytes); Keyfactory factory = keyfactory.getInstance (key_algorithm); PrivateKey Prikey = Factory.GeneratePrivate (KEYSPEC); // Gere a chave privada // DigitSign Information com assinatura de chave privada assinatura = assinatura.getInstance (Signature_alGorithm); Signature.initsign (Prikey); assinatura.Update (dados); retornar EncryptBase64 (Signature.sign ()); } / *** base64Encoder criptografia* @param dados de dados a serem criptografados* @return string criptografada* / private static string EncryptBase64 (byte [] data) {base64Encoder coder = new Base64Encoder (); String cody cody = coder.encode (dados); retornar codificar; } / *** base64decoder descriptografar* @param string de dados a ser decrypt* @return byte descripitado []* @throws Exceção* / byte estático privado [] decyptBase64 (dados de string) lança exceção {base64decoder decoder = novo base64decoder (); byte [] buffer = decoder.DecodeBuffer (Data); retornar buffer; } / *** Verifique a assinatura digital* @Param Data Data criptografada* @param publicKey* @param assinatura assinatura digital* @return* @throws Exceção* / public static boolean verify (byte [] dados, string publicKey, string signo) lança exceção {byte [] keybytes = DecryptBase6 (signo); X509EncodedKeyspec Keyspec = novo x509EncodedKeyspec (KeyBytes); KeyFactory keyFactory = keyFactory.getInstance (key_algorithm); PublicKey PubKey = KeyFactory.GeneratePublic (Keyspec); Assinatura assinatura = assinatura.getInstance (assinatura_algorithm); Signature.initVerify (PubKey); assinatura.Update (dados); retornar assinatura.Verify (decryptBase64 (sinal)); // Verifique a assinatura}}