<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ledio5485</id>
		<title>OWASP - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ledio5485"/>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php/Special:Contributions/Ledio5485"/>
		<updated>2026-05-26T03:05:55Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.2</generator>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=OWASP_Java_Project_WIPRO_1_2015&amp;diff=217383</id>
		<title>OWASP Java Project WIPRO 1 2015</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=OWASP_Java_Project_WIPRO_1_2015&amp;diff=217383"/>
				<updated>2016-05-25T21:44:27Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Pages List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;width:100%;border:0,margin:0;overflow: hidden;&amp;quot;&amp;gt;[[File:OWASP_Java_Project_Header.png|link=]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;font-size: 1.8em;&amp;quot;&amp;gt;Wiki Pages Review Operation - 2015/2016&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Main =&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;padding: 0;margin:0;margin-top:10px;text-align:left;&amp;quot; |-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; style=&amp;quot;border-right: 1px dotted gray;padding-right:25px;width:100%&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
91 Pages in category &amp;quot;OWASP Java Pages&amp;quot; have to be reviewed. We use a Google Document where every person interested can let opinions, comments and suggestions. Even reviewing one single page is welcome. &lt;br /&gt;
&lt;br /&gt;
Shared Google document used to comment and review:&lt;br /&gt;
&lt;br /&gt;
https://docs.google.com/spreadsheets/d/13bazikNd5fc9f7ppqMEAxbo0sI3CpOdPgDW5xt3LeMc/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;  style=&amp;quot;padding-left:25px;min-width:200px;border-right: 1px dotted gray;padding-right:25px;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
* Start: 12/2015&lt;br /&gt;
* Last Update: 12/2015&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Resources ==&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;  style=&amp;quot;padding-left:25px;min-width:200px;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==Classifications==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
   {| width=&amp;quot;200&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
   |-&lt;br /&gt;
   | align=&amp;quot;center&amp;quot; valign=&amp;quot;top&amp;quot; width=&amp;quot;50%&amp;quot; rowspan=&amp;quot;2&amp;quot;| [[File:Owasp-incubator-trans-85.png|link=https://www.owasp.org/index.php/OWASP_Project_Stages#tab=Incubator_Projects]]&lt;br /&gt;
   | align=&amp;quot;center&amp;quot; valign=&amp;quot;top&amp;quot; width=&amp;quot;50%&amp;quot;| [[File:Owasp-builders-small.png|link=]]  &lt;br /&gt;
   |-&lt;br /&gt;
   | align=&amp;quot;center&amp;quot; valign=&amp;quot;top&amp;quot; width=&amp;quot;50%&amp;quot;| [[File:Owasp-defenders-small.png|link=]]&lt;br /&gt;
   |-&lt;br /&gt;
   | colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;  | [[File:Cc-button-y-sa-small.png|link=http://creativecommons.org/licenses/by-sa/3.0/]]&lt;br /&gt;
   |-&lt;br /&gt;
   | colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;  | [[File:Project_Type_Files_DOC.jpg|link=]]&lt;br /&gt;
   |}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Pages List =&lt;br /&gt;
&lt;br /&gt;
Shared Google document used to write reviews:&lt;br /&gt;
&lt;br /&gt;
https://docs.google.com/spreadsheets/d/13bazikNd5fc9f7ppqMEAxbo0sI3CpOdPgDW5xt3LeMc/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Page&lt;br /&gt;
! Status&lt;br /&gt;
! Review&lt;br /&gt;
! Operations&lt;br /&gt;
|- &lt;br /&gt;
|[[Bytecode obfuscation]]&lt;br /&gt;
|&lt;br /&gt;
| Outdated but interesting to keep, marked for review. https://www.owasp.org/index.php/Talk:Bytecode_obfuscation&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Captchas in Java ]]&lt;br /&gt;
|&lt;br /&gt;
|Updated and not of interest. Marked for deletion.&lt;br /&gt;
|DELETED BY ADMIN&lt;br /&gt;
|-&lt;br /&gt;
|[[Clickjacking Protection for Java EE]]&lt;br /&gt;
|&lt;br /&gt;
|Flagged for deletion, reason stated on page.&lt;br /&gt;
|DELETED BY ADMIN&lt;br /&gt;
|-&lt;br /&gt;
|[[Command injection in Java]]&lt;br /&gt;
|&lt;br /&gt;
|Marked for review.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Comparing classes by name ]]&lt;br /&gt;
|&lt;br /&gt;
|Marked for review&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Complejidad Y Longitud De Las Contraseñas ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Content Security Policy ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[CORS OriginHeaderScrutiny]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[CORS RequestPreflighScrutiny]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Cross-site Scripting (XSS) ]]&lt;br /&gt;
|&lt;br /&gt;
| Looks updated&lt;br /&gt;
| NO ACTION TAKEN&lt;br /&gt;
|-&lt;br /&gt;
|[[Declarative Access Control in Java]]&lt;br /&gt;
|&lt;br /&gt;
|gone&lt;br /&gt;
|Deleted by admin&lt;br /&gt;
|-&lt;br /&gt;
|[[Decompiling Java bytecode]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| DELETED&lt;br /&gt;
|-&lt;br /&gt;
|[[Deserialization of untrusted data]]&lt;br /&gt;
|&lt;br /&gt;
| Looks legit&lt;br /&gt;
| Looks legit&lt;br /&gt;
|-&lt;br /&gt;
|[[Detect profiling phase into web application]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Exception handling techniques ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Failure to follow guideline/specification ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Hacking Java Clients ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Hashing Java]]&lt;br /&gt;
| UNDER REVIEW&lt;br /&gt;
| Updated by Mark Gordon. Thank you!&lt;br /&gt;
| No action needed&lt;br /&gt;
|-&lt;br /&gt;
|[[Hibernate]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Hibernate-Guidelines ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[How to add validation logic to HttpServletRequest]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[How to encrypt a properties file ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Implementacion De Firmas Digitales en Java]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Improper Data Validation]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Improper temp file opening ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Information Leakage]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Insecure Randomness]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Insecure Transport]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Insufficient Session-ID Length]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Invoking untrusted mobile code]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Inyección De Comandos En Java ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[J2EE Misconfiguration: Unsafe Bean Declaration]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[J2EE third party libraries insecurity]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| redirected to dependency check&lt;br /&gt;
|-&lt;br /&gt;
|[[JAAS Timed Login Module ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| Deleted&lt;br /&gt;
|-&lt;br /&gt;
|[[JAAS Tomcat Login Module]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| Deleted&lt;br /&gt;
|-&lt;br /&gt;
|[[Java Project Article Wishlist ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Java Security Frameworks]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| Merged into category page&lt;br /&gt;
|-&lt;br /&gt;
|[[Java Security Resources ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| Merged into category page&lt;br /&gt;
|-&lt;br /&gt;
|[[Java Server Faces ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[JSP errorPage]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[JSP JSTL ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Leftover Debug Code]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Log Forging ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Logout]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Member Field Race Condition]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Missing Error Handling]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Mobile Java Security ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Null Dereference]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Object Model Violation: Just One of equals() and hashCode() Defined]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Often Misused: Authentication ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Overly-Broad Catch Block]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Overly-Broad Throws Declaration]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[OWASP CSRFGuard Project/es ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[OWASP Java Table of Contents]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Parameter Validation Filter]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Password length &amp;amp; complexity]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Password Management: Hardcoded Password]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Password Management: Weak Cryptography ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Password Plaintext Storage ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[PDF Attack Filter for Java EE ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Poor Logging Practice]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Preventing LDAP Injection in Java]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|[[Preventing SQL Injection in Java ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|redirected to sqlI cheatsheet&lt;br /&gt;
|-&lt;br /&gt;
|[[Process Control]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Protecting code archives with digital signatures]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Reflection attack in an auth protocol]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Return Inside Finally Block]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Securing tomcat]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Servlet spec - web.xml]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Session Fixation]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Session Timeout]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Signing jar files with jarsigner ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[State synchronization error]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Struts]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Struts Validation in an ActionForm]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Struts Validation in validator.xml using an ActionForm]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Struts XSLT Viewer]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Traducción Español]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Trust Boundary Violation]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Trustworthy Java]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| Delete&lt;br /&gt;
|-&lt;br /&gt;
|[[Uncaught exception]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Unchecked Return Value: Missing Check against Null ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Unreleased Resource]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Unsafe JNI]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Unsafe Mobile Code]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Unsafe Reflection ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Using JCaptcha ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| deleted&lt;br /&gt;
|-&lt;br /&gt;
|[[Using the Java Cryptographic Extensions]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Using the Java Secure Socket Extensions]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[XPATH Injection Java ]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[OWASP's_ESAPI_Wiki_for_Java!]]&lt;br /&gt;
| Check Project Status&lt;br /&gt;
|&lt;br /&gt;
| The entire ESAPI For Java project needs a review. In progress on ML.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Shared Google document used to write reviews:&lt;br /&gt;
&lt;br /&gt;
https://docs.google.com/spreadsheets/d/13bazikNd5fc9f7ppqMEAxbo0sI3CpOdPgDW5xt3LeMc/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
=About=&lt;br /&gt;
&lt;br /&gt;
OWASP Java and JVM Project - Wiki Pages Review Operation 1 - 2015/2016&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Template:Project About&lt;br /&gt;
| project_name =OWASP Java Project WIPRO 1 - 2015/2016&lt;br /&gt;
| project_description = &lt;br /&gt;
| project_license =&lt;br /&gt;
| leader_name1 = &lt;br /&gt;
| leader_email1 = &lt;br /&gt;
| leader_username1 = &lt;br /&gt;
| contributor_name1 = &lt;br /&gt;
| contributor_email1 = &lt;br /&gt;
| contributor_username1 = &lt;br /&gt;
| mailing_list_name = &lt;br /&gt;
| links_url1 = &lt;br /&gt;
| links_name1 = &lt;br /&gt;
| links_url2 = &lt;br /&gt;
| links_name2 = &lt;br /&gt;
}}  &lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&amp;lt;headertabs /&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217382</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217382"/>
				<updated>2016-05-25T21:23:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your first and last name? &lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correct?&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for  &amp;amp;lt;testsender&amp;amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Enter the password of KeyStore: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the country code of two letters for this unit?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correct? &lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Code Example  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
/ **&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Encrypt data using a symmetric key &lt;br /&gt;
 * 2. Encrypt the symmetric key with the public key Receivers &lt;br /&gt;
 * 3. Create a message digest of the data to be transmitted &lt;br /&gt;
 * 4. Sign the message to be transmitted &lt;br /&gt;
 * 5. Send the data through a nonsecure channel &lt;br /&gt;
 * 6. Validate signature&lt;br /&gt;
 * 7. Decoding the message using the private key Pets for the symmetric key &lt;br /&gt;
 * 8. Deciphering the data using the symmetric key &lt;br /&gt;
 * 9. Calculate MessageDigest signed message data +&lt;br /&gt;
 * 10.Valide if the text message digest matches the decrypted message digest of the original message &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
		// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
	// 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
	// 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplications in Free Environments'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Translator:''' Bravo Maria Jose and Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217381</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217381"/>
				<updated>2016-05-25T21:01:11Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* PublicKeyCryptography.java */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your first and last name? &lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correct?&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for  &amp;amp;lt;testsender&amp;amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Enter the password of KeyStore: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the country code of two letters for this unit?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correct? &lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Code Example  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
/ **&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Encrypt data using a symmetric key &lt;br /&gt;
 * 2. Encrypt the symmetric key with the public key Receivers &lt;br /&gt;
 * 3. Create a message digest of the data to be transmitted &lt;br /&gt;
 * 4. Sign the message to be transmitted &lt;br /&gt;
 * 5. Send the data through a nonsecure channel &lt;br /&gt;
 * 6. Validate signature&lt;br /&gt;
 * 7. Decoding the message using the private key Pets for the symmetric key &lt;br /&gt;
 * 8. Deciphering the data using the symmetric key &lt;br /&gt;
 * 9. Calculate MessageDigest signed message data +&lt;br /&gt;
 * 10.Valide if the text message digest matches the decrypted message digest of the original message &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
		// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
	// 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
	// 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217380</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217380"/>
				<updated>2016-05-25T20:57:33Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* PublicKeyCryptography.java */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your first and last name? &lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correct?&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for  &amp;amp;lt;testsender&amp;amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Enter the password of KeyStore: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the country code of two letters for this unit?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correct? &lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Code Example  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ **&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Encrypt data using a symmetric key &lt;br /&gt;
 * 2. Encrypt the symmetric key with the public key Receivers &lt;br /&gt;
 * 3. Create a message digest of the data to be transmitted &lt;br /&gt;
 * 4. Sign the message to be transmitted &lt;br /&gt;
 * 5. Send the data through a nonsecure channel &lt;br /&gt;
 * 6. Validate signature&lt;br /&gt;
 * 7. Decoding the message using the private key Pets for the symmetric key &lt;br /&gt;
 * 8. Deciphering the data using the symmetric key &lt;br /&gt;
 * 9. Calculate MessageDigest signed message data +&lt;br /&gt;
 * 10.Valide if the text message digest matches the decrypted message digest of the original message &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217379</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217379"/>
				<updated>2016-05-25T20:55:57Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Code Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your first and last name? &lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correct?&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for  &amp;amp;lt;testsender&amp;amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Enter the password of KeyStore: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the country code of two letters for this unit?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correct? &lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Code Example  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217378</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217378"/>
				<updated>2016-05-25T20:54:11Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Commands for key generation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your first and last name? &lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correct?&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for  &amp;amp;lt;testsender&amp;amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Enter the password of KeyStore: testpwd &lt;br /&gt;
&lt;br /&gt;
What is your name?&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
What is the name of the OU?&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
What is the name of your organization?&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
What is the name of your city or town?&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
What is the name of your state or province?&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
What is the country code of two letters for this unit?&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Is CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correct? &lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Enter the key password for &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217377</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217377"/>
				<updated>2016-05-25T20:39:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Comandos para la generación de claves */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Commands for key generation  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217376</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217376"/>
				<updated>2016-05-25T20:38:05Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Algorithm to implement digital signature using the RSA algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algorithm to implement digital signature using the RSA algorithm  ==&lt;br /&gt;
&lt;br /&gt;
The provider RSA Java implementation has a limitation in that encryption can be performed on the data length &amp;lt;= 117 bytes only. If the data is of a length&amp;gt; 117 bytes, it will launch a IllegalBlockSizeException: Data must have more than 117 bytes symmetry there has to be encrypted and then signed.&lt;br /&gt;
&lt;br /&gt;
RSA PKCS # 1 algorithm can only encrypt data size k - 11, where k whose length is one byte and the RSA module 11 is the number of bytes used by the filling PCKS # 1 v1.5. Therefore, if we use an RSA key size of 1024 bits, we could encrypt only 128-11 =&amp;gt; 117 bytes of data. There are two options available to encrypt data byte size larger.&lt;br /&gt;
&lt;br /&gt;
#We could use an RSA key length&amp;gt; 1024. For example, using 2048 bits, then we could encrypt 256-11 =&amp;gt; 245 bytes of data. The disadvantage of this approach is that it would be capable of encoding data size&amp;gt; x bytes (in the above example x is 245).&lt;br /&gt;
#Analyze the input data chunks of bytes in size &amp;lt;117 and apply encryption on each piece. The code example of this approach can be found [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Both approaches could affect performance since the RSA key larger or approach of [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms &amp;quot;divide and conquer&amp;quot;] of input bytes are computationally expensive.&lt;br /&gt;
&lt;br /&gt;
=== Algorithm  ===&lt;br /&gt;
&lt;br /&gt;
With the foregoing, the following algorithm can be used for the implementation of public key cryptography in Java. &lt;br /&gt;
&lt;br /&gt;
#Encrypt the message using a symmetric key&lt;br /&gt;
#Concatenate the symmetric key + symmetric hash + hash key message.&lt;br /&gt;
#Encrypt the concatenated string with the public key of the recipient.&lt;br /&gt;
#Sign data to be transmitted (encrypted symmetric key + the + Hash hash key message).&lt;br /&gt;
#Validate the signature.&lt;br /&gt;
#Deciphering the message with the recipient's private key to obtain the symmetric key.&lt;br /&gt;
#Validate the integrity of the key using the hash key.&lt;br /&gt;
#It decipher the real message using the symmetric key that has been decrypted, analyzed and integrity checks.&lt;br /&gt;
#Calculate MessageDigest of data.&lt;br /&gt;
#Validate whether the message digest decrypted text matches the message digest of the original message. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217375</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217375"/>
				<updated>2016-05-25T20:24:13Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Digital signatures in Java using JCA */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Digital signatures in Java using JCA  ==&lt;br /&gt;
&lt;br /&gt;
Java Cryptography Architecture is a framework for accessing and developing cryptographic functionality for the Java platform. JCA provider implements cryptographic functionality such as digital signatures and message digests. The default JCA provider is SUN JDK 1.4.2. &lt;br /&gt;
&lt;br /&gt;
=== Security considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Two major safety considerations that must be taken into account when applying digital signatures are:&lt;br /&gt;
&lt;br /&gt;
#Sign the message and then encrypt the signed message.&lt;br /&gt;
#Sign the hash of the message instead of the entire message. &lt;br /&gt;
&lt;br /&gt;
=== Performance considerations when implementing digital signature ===&lt;br /&gt;
&lt;br /&gt;
Because asymmetric encryption algorithms such as RSA, DSA are computationally slower than symmetric encryption algorithms such as AES, it is a good practice, encrypt the actual message that is transmitted using a symmetric key algorithm and then encrypt the key that is used in symmetric key algorithm using an asymmetric key algorithm. For example, if you want to convey the message &amp;quot;Hello World Digital Signatures&amp;quot;, then this message is first encrypted with a symmetric key, for example, an AES 128-bit key as x7oFaHSPnWxEMiZE/0qYrg and then this key is encrypted with an algorithm as RSA asymmetric key.&lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217374</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217374"/>
				<updated>2016-05-25T20:19:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Need for Digital Signature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Need for Digital Signature  ===&lt;br /&gt;
&lt;br /&gt;
During the &amp;quot;E&amp;quot; revolution was a need for authentication of critical transactions especially in the financial world. If Alice agreed to transfer $ x to Bob, then there had to be a way for Bob to ensure that:&lt;br /&gt;
&lt;br /&gt;
*It was Alice who performed the transaction and not someone else impersonating Alice (Authentication).&lt;br /&gt;
*The amount agreed by Alice is $ x (Integrity).&lt;br /&gt;
*Alice could not discuss his statement transaction $ x a Bob (Non-repudiation of origin).&lt;br /&gt;
&lt;br /&gt;
These concerns were treated with a solution known as digital signatures. More background information on digital signatures can be found [http://en.wikipedia.org/wiki/Digital_signature here]&lt;br /&gt;
&lt;br /&gt;
== Firmas digitales en Java utilizando JCA  ==&lt;br /&gt;
&lt;br /&gt;
La Arquitectura de Java Cryptography es un marco para el acceso y el desarrollo de la funcionalidad criptográfica para la plataforma Java. Un proveedor de JCA implementa las funcionalidades criptográficas como firmas digitales y compendios de mensajes. El proveedor predeterminado JCA en JDK 1.4.2 es SUN. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones de seguridad al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dos consideraciones principales de seguridad que se deben tener en cuenta al aplicar firmas digitales son:&lt;br /&gt;
&lt;br /&gt;
#Firma el mensaje y, a continuación cifrar el mensaje firmado.&lt;br /&gt;
#Firma el hash del mensaje en lugar del mensaje completo. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones sobre el rendimiento al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dado que los algoritmos de cifrado asimétricos, como RSA, DSA son computacionalmente más lento que los algoritmos de cifrado simétricos como AES, es una buena práctica, cifrar el mensaje real que se transmite utilizando un algoritmo de clave simétrica y luego cifrar la clave que se utiliza en el algoritmo de clave simétrica utilizando un algoritmo de clave asimétrica. Por ejemplo: si se quiere transmitir el mensaje &amp;quot;Hola Mundo de Firmas Digitales&amp;quot;, entonces primero se cifra este mensaje con una clave simétrica, por ejemplo una clave AES de 128 bits como x7oFaHSPnWxEMiZE/0qYrg y luego se cifra esta clave con un algoritmo de clave asimétrica como RSA. &lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217373</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217373"/>
				<updated>2016-05-25T20:15:48Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* What is a digital signature? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== What is a digital signature?  ===&lt;br /&gt;
&lt;br /&gt;
A digital signature is a concept that helps to get the non-repudiation of origin (ie, the integrity of Origin) data. By digitally signing the document, the person signing, says he is the author of the document or the signed message.&lt;br /&gt;
&lt;br /&gt;
=== Necesidad de Firma Digital  ===&lt;br /&gt;
&lt;br /&gt;
Durante la &amp;quot;E&amp;quot; revolución, fue una necesidad para la autenticación de críticas transacciones sobre todo en el mundo financiero. Si Alice se comprometió a transferir $ x para Bob, entonces tenía que haber una manera para que Bob se asegure de que:&lt;br /&gt;
&lt;br /&gt;
*Fue Alice quien realizó la transacción y no otra persona suplantando Alice (Autenticación).&lt;br /&gt;
*El monto acordado por Alice es $x (Integridad).&lt;br /&gt;
*Alicia no pudo discutir su declaración de transacción $x a Bob (No repudio de origen).&lt;br /&gt;
&lt;br /&gt;
Estas preocupaciones fueron tratadas con una solución conocida como firmas digitales. Más información de fondo sobre las firmas digitales se puede encontrar en [http://en.wikipedia.org/wiki/Digital_signature Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
== Firmas digitales en Java utilizando JCA  ==&lt;br /&gt;
&lt;br /&gt;
La Arquitectura de Java Cryptography es un marco para el acceso y el desarrollo de la funcionalidad criptográfica para la plataforma Java. Un proveedor de JCA implementa las funcionalidades criptográficas como firmas digitales y compendios de mensajes. El proveedor predeterminado JCA en JDK 1.4.2 es SUN. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones de seguridad al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dos consideraciones principales de seguridad que se deben tener en cuenta al aplicar firmas digitales son:&lt;br /&gt;
&lt;br /&gt;
#Firma el mensaje y, a continuación cifrar el mensaje firmado.&lt;br /&gt;
#Firma el hash del mensaje en lugar del mensaje completo. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones sobre el rendimiento al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dado que los algoritmos de cifrado asimétricos, como RSA, DSA son computacionalmente más lento que los algoritmos de cifrado simétricos como AES, es una buena práctica, cifrar el mensaje real que se transmite utilizando un algoritmo de clave simétrica y luego cifrar la clave que se utiliza en el algoritmo de clave simétrica utilizando un algoritmo de clave asimétrica. Por ejemplo: si se quiere transmitir el mensaje &amp;quot;Hola Mundo de Firmas Digitales&amp;quot;, entonces primero se cifra este mensaje con una clave simétrica, por ejemplo una clave AES de 128 bits como x7oFaHSPnWxEMiZE/0qYrg y luego se cifra esta clave con un algoritmo de clave asimétrica como RSA. &lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217372</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217372"/>
				<updated>2016-05-25T20:14:00Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the [http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html Java Cryptography Architecture (JCA)].&lt;br /&gt;
&lt;br /&gt;
=== ¿Qué es una firma digital?  ===&lt;br /&gt;
&lt;br /&gt;
Una firma digital es un concepto que ayuda a obtener el no repudio de origen (es decir, la Integridad del Origen) de datos. Al firmar digitalmente el documento, la persona que firma, asegura que él es el autor del documento o el mensaje firmado. &lt;br /&gt;
&lt;br /&gt;
=== Necesidad de Firma Digital  ===&lt;br /&gt;
&lt;br /&gt;
Durante la &amp;quot;E&amp;quot; revolución, fue una necesidad para la autenticación de críticas transacciones sobre todo en el mundo financiero. Si Alice se comprometió a transferir $ x para Bob, entonces tenía que haber una manera para que Bob se asegure de que:&lt;br /&gt;
&lt;br /&gt;
*Fue Alice quien realizó la transacción y no otra persona suplantando Alice (Autenticación).&lt;br /&gt;
*El monto acordado por Alice es $x (Integridad).&lt;br /&gt;
*Alicia no pudo discutir su declaración de transacción $x a Bob (No repudio de origen).&lt;br /&gt;
&lt;br /&gt;
Estas preocupaciones fueron tratadas con una solución conocida como firmas digitales. Más información de fondo sobre las firmas digitales se puede encontrar en [http://en.wikipedia.org/wiki/Digital_signature Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
== Firmas digitales en Java utilizando JCA  ==&lt;br /&gt;
&lt;br /&gt;
La Arquitectura de Java Cryptography es un marco para el acceso y el desarrollo de la funcionalidad criptográfica para la plataforma Java. Un proveedor de JCA implementa las funcionalidades criptográficas como firmas digitales y compendios de mensajes. El proveedor predeterminado JCA en JDK 1.4.2 es SUN. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones de seguridad al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dos consideraciones principales de seguridad que se deben tener en cuenta al aplicar firmas digitales son:&lt;br /&gt;
&lt;br /&gt;
#Firma el mensaje y, a continuación cifrar el mensaje firmado.&lt;br /&gt;
#Firma el hash del mensaje en lugar del mensaje completo. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones sobre el rendimiento al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dado que los algoritmos de cifrado asimétricos, como RSA, DSA son computacionalmente más lento que los algoritmos de cifrado simétricos como AES, es una buena práctica, cifrar el mensaje real que se transmite utilizando un algoritmo de clave simétrica y luego cifrar la clave que se utiliza en el algoritmo de clave simétrica utilizando un algoritmo de clave asimétrica. Por ejemplo: si se quiere transmitir el mensaje &amp;quot;Hola Mundo de Firmas Digitales&amp;quot;, entonces primero se cifra este mensaje con una clave simétrica, por ejemplo una clave AES de 128 bits como x7oFaHSPnWxEMiZE/0qYrg y luego se cifra esta clave con un algoritmo de clave asimétrica como RSA. &lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217371</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217371"/>
				<updated>2016-05-25T20:12:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
  &lt;br /&gt;
This article presents a brief overview of the concepts involved with digital signatures and provides code examples for the application of digital signatures in Java using the Java Cryptography Architecture.&lt;br /&gt;
&lt;br /&gt;
=== ¿Qué es una firma digital?  ===&lt;br /&gt;
&lt;br /&gt;
Una firma digital es un concepto que ayuda a obtener el no repudio de origen (es decir, la Integridad del Origen) de datos. Al firmar digitalmente el documento, la persona que firma, asegura que él es el autor del documento o el mensaje firmado. &lt;br /&gt;
&lt;br /&gt;
=== Necesidad de Firma Digital  ===&lt;br /&gt;
&lt;br /&gt;
Durante la &amp;quot;E&amp;quot; revolución, fue una necesidad para la autenticación de críticas transacciones sobre todo en el mundo financiero. Si Alice se comprometió a transferir $ x para Bob, entonces tenía que haber una manera para que Bob se asegure de que:&lt;br /&gt;
&lt;br /&gt;
*Fue Alice quien realizó la transacción y no otra persona suplantando Alice (Autenticación).&lt;br /&gt;
*El monto acordado por Alice es $x (Integridad).&lt;br /&gt;
*Alicia no pudo discutir su declaración de transacción $x a Bob (No repudio de origen).&lt;br /&gt;
&lt;br /&gt;
Estas preocupaciones fueron tratadas con una solución conocida como firmas digitales. Más información de fondo sobre las firmas digitales se puede encontrar en [http://en.wikipedia.org/wiki/Digital_signature Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
== Firmas digitales en Java utilizando JCA  ==&lt;br /&gt;
&lt;br /&gt;
La Arquitectura de Java Cryptography es un marco para el acceso y el desarrollo de la funcionalidad criptográfica para la plataforma Java. Un proveedor de JCA implementa las funcionalidades criptográficas como firmas digitales y compendios de mensajes. El proveedor predeterminado JCA en JDK 1.4.2 es SUN. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones de seguridad al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dos consideraciones principales de seguridad que se deben tener en cuenta al aplicar firmas digitales son:&lt;br /&gt;
&lt;br /&gt;
#Firma el mensaje y, a continuación cifrar el mensaje firmado.&lt;br /&gt;
#Firma el hash del mensaje en lugar del mensaje completo. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones sobre el rendimiento al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dado que los algoritmos de cifrado asimétricos, como RSA, DSA son computacionalmente más lento que los algoritmos de cifrado simétricos como AES, es una buena práctica, cifrar el mensaje real que se transmite utilizando un algoritmo de clave simétrica y luego cifrar la clave que se utiliza en el algoritmo de clave simétrica utilizando un algoritmo de clave asimétrica. Por ejemplo: si se quiere transmitir el mensaje &amp;quot;Hola Mundo de Firmas Digitales&amp;quot;, entonces primero se cifra este mensaje con una clave simétrica, por ejemplo una clave AES de 128 bits como x7oFaHSPnWxEMiZE/0qYrg y luego se cifra esta clave con un algoritmo de clave asimétrica como RSA. &lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Deserialization_of_untrusted_data&amp;diff=217370</id>
		<title>Deserialization of untrusted data</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Deserialization_of_untrusted_data&amp;diff=217370"/>
				<updated>2016-05-25T18:51:02Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Vulnerability}}&lt;br /&gt;
{{Template:SecureSoftware}}&lt;br /&gt;
&lt;br /&gt;
Last revision (mm/dd/yy): '''{{REVISIONMONTH}}/{{REVISIONDAY}}/{{REVISIONYEAR}}'''&lt;br /&gt;
&lt;br /&gt;
[[ASDR_TOC_Vulnerabilities|Vulnerabilities Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
&lt;br /&gt;
Data which is untrusted cannot be trusted to be well formed. Malformed data or unexpected data could be used to abuse application logic, deny service, or execute arbitrary code, when deserialized.&lt;br /&gt;
&lt;br /&gt;
'''Consequences'''&lt;br /&gt;
&lt;br /&gt;
* Availability: The logic of deserialization could be abused to create recursive object graphs or never provide data expected to terminate reading.&lt;br /&gt;
* Authorization: Potentially code could make assumptions that information in the deserialized object about the data is valid. Functions which make this dangerous assumption could be exploited.&lt;br /&gt;
* Access control (instruction processing): malicious objects can abuse the logic of custom deserializers in order to affect code execution.&lt;br /&gt;
&lt;br /&gt;
'''Exposure period'''&lt;br /&gt;
&lt;br /&gt;
* Requirements specification: A deserialization library could be used which provides a cryptographic framework to seal serialized data. &lt;br /&gt;
* Implementation: Not using the safe deserialization/serializing data features of a language can create data integrity problems. &lt;br /&gt;
* Implementation: Not using the protection accessor functions of an object can cause data integrity problems &lt;br /&gt;
* Implementation: Not protecting your objects from default overloaded functions - which may provide for raw output streams of objects - may cause data confidentiality problems. &lt;br /&gt;
* Implementation: Not making fields transient can often cause data confidentiality problems.&lt;br /&gt;
&lt;br /&gt;
'''Platform'''&lt;br /&gt;
&lt;br /&gt;
* Languages: C, C++, Java, Python, Ruby (and probably others)&lt;br /&gt;
* Operating platforms: Any&lt;br /&gt;
&lt;br /&gt;
'''Required resources'''&lt;br /&gt;
&lt;br /&gt;
Any&lt;br /&gt;
&lt;br /&gt;
'''Severity'''&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
'''Likelihood of exploit'''&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
It is often convenient to serialize objects for convenient communication or to save them for later use. However, deserialized data or code can often be modified without using the provided accessor functions if it does not use cryptography to protect itself. Furthermore, any cryptography would still be client-side security - which is of course a dangerous security assumption.&lt;br /&gt;
&lt;br /&gt;
An attempt to serialize and then deserialize a class containing transient fields will result in NULLs where the non-transient data should be. This is an excellent way to prevent time, environment-based, or sensitive variables from being carried over and used improperly.&lt;br /&gt;
&lt;br /&gt;
==Risk Factors==&lt;br /&gt;
&lt;br /&gt;
* Does the deserialization take place before authentication?&lt;br /&gt;
* Does the deserialization limit which types can be deserialized?&lt;br /&gt;
* Does the deserialization host have types available which can be repurposed towards malicious ends? Sometimes, these types are called &amp;quot;gadgets&amp;quot;, considering their similarity to abusable bits of code that already exist in machine code in [https://en.wikipedia.org/wiki/Return-oriented_programming Return-Oriented-Programming] attacks.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
The following is an example from Adobe's BlazeDS AMF deserialization vulnerability ([https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-2092 CVE-2011-2092]). You can specify arbitrary classes and properties for a BlazeDS application to deserialize. This particular payload creates an instance of a JFrame object on the target server. The created JFrame object will have a &amp;quot;defaultCloseOperation&amp;quot; of value 3 -- which indicates that the JVM should exit when this JFrame window is closed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[RemoteClass(alias=&amp;quot;javax.swing.JFrame&amp;quot;)]&lt;br /&gt;
public class JFrame {&lt;br /&gt;
   public var title:String = &amp;quot;Gotcha!&amp;quot;;&lt;br /&gt;
   public var defaultCloseOperation:int = 3;&lt;br /&gt;
   public var visible:Boolean = true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next example is one that is much more likely to be seen in custom code. This code reads an object from an untrusted source, and then casts it to an AcmeObject:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
InputStream is = request.getInputStream();&lt;br /&gt;
ObjectInputStream ois = new ObjectInputStream(is);&lt;br /&gt;
AcmeObject acme = (AcmeObject)ois.readObject();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the casting operation to AcmeObject occurs after the deserialization process ends. Therefore, it's not useful in preventing any attacks that happen during deserialization from occurring. It's possible that behavior in custom deserialization protocols (for instance, by overriding Serializable#readObject() in Java) can be re-purposed towards malicious ends. Researchers have found [http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ complex object graphs which, when deserialized, can lead to remote code execution] in most Java software.&lt;br /&gt;
&lt;br /&gt;
The next example is a denial-of-service attack against any Java application that allows deserialization. The HashSet called &amp;quot;root&amp;quot; in the following code sample has members that are recursively linked to each other. When deserializing this &amp;quot;root&amp;quot; object, the JVM will begin creating a recursive object graph. It will never complete, and consume CPU indefinitely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Set root = new HashSet();&lt;br /&gt;
Set s1 = root;&lt;br /&gt;
Set s2 = new HashSet();&lt;br /&gt;
for (int i = 0; i &amp;lt; 100; i++) {&lt;br /&gt;
  Set t1 = new HashSet();&lt;br /&gt;
  Set t2 = new HashSet();&lt;br /&gt;
  t1.add(&amp;quot;foo&amp;quot;); // make it not equal to t2&lt;br /&gt;
  s1.add(t1);&lt;br /&gt;
  s1.add(t2);&lt;br /&gt;
  s2.add(t1);&lt;br /&gt;
  s2.add(t2);&lt;br /&gt;
  s1 = t1;&lt;br /&gt;
  s2 = t2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example of a denial-of-service attack against any Java application that allows deserialization:  &lt;br /&gt;
&lt;br /&gt;
By crafting a stream, such that it contains an ArrayList with a size of Integer.MAX_VALUE, even if all elements are null or the same object, an internal array of length MAX_VALUE will be created, on some JVM's this will cause an OutOfMemoryError prior to deserialization of the elements, this doesn't require much data in the inputStream.  Many collection classes and object arrays can be manipulated in similar wasy, as they create their capacity prior to reading in elements, few sanity checks are performed.&lt;br /&gt;
&lt;br /&gt;
It's not like the JVM folks aren't aware, they're just hamstrung by backward compatibility with deployed code.&lt;br /&gt;
&lt;br /&gt;
A quote from ArrayList source (GPL2 license with classpath exception):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * The maximum size of array to allocate.&lt;br /&gt;
     * Some VMs reserve some header words in an array.&lt;br /&gt;
     * Attempts to allocate larger arrays may result in&lt;br /&gt;
     * OutOfMemoryError: Requested array size exceeds VM limit&lt;br /&gt;
     */&lt;br /&gt;
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even if ObjectInputStream is overridden to perform look ahead deserialization with a white-list, ObjectInputStream itself, will allow an attacker to create a multidimensional array, with a size of Integer.MAX_VALUE and every array element it contains, to do the same, even if these arrays all contain the same object element reference (passing reference to cached, previously serialized objects, minimizes the stream bytes transferred), it will very quickly consume all available memory in the JVM.&lt;br /&gt;
&lt;br /&gt;
Fortunately ObjectInputStream can be completely re-implemented and overridden by subclassing, in this case the entire functionality of ObjectInputStream has to also be re-implemented to read [https://docs.oracle.com/javase/7/docs/platform/serialization the Java serialization protocol].  &lt;br /&gt;
&lt;br /&gt;
Since Java's Serialization uses implicit construction, whereby the first non serializable no argument super class constructor is invoked to create a child class instance (along with some unsafe magic), it prevents classes from checking their invariant's until after construction has completed.  For this reason, the standard implicit java Serialization API is flawed from a security perspective.&lt;br /&gt;
&lt;br /&gt;
It is possible to create an ObjectInputStream that is backward compatible with current Serializable Object's serial form, for security, it requires a new deserialization API, the exclusion of circular references, limits placed on array lengths and the object cache, all while allowing classes to check their invariants prior to objects being created, such that no object can be created in an illegal state.  In addition administrators will need to be able to reduce the classes available for deserialization to only those required to limit the attack surface, similar to white-listing or using Permission's.&lt;br /&gt;
&lt;br /&gt;
==Related [[Controls]]==&lt;br /&gt;
&lt;br /&gt;
* Requirements specification: A deserialization library could be used which provides a cryptographic framework to seal serialized data. &lt;br /&gt;
* Implementation: Use the signing features of a language to assure that deserialized data has not been tainted. &lt;br /&gt;
* Implementation: When deserializing data, populate a new object rather than just deserializing. The result is that the data flows through safe input validation and that the functions are safe. &lt;br /&gt;
* Implementation: Explicitly define final [http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html readObject()] to prevent deserialization. &lt;br /&gt;
&lt;br /&gt;
An example of this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private final void readObject(ObjectInputStream in)&lt;br /&gt;
throws java.io.IOException {&lt;br /&gt;
     throw new java.io.IOException(&amp;quot;Cannot be deserialized&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Implementation: Make fields transient to protect them from deserialization.&lt;br /&gt;
* Implementation: In your code, override the [http://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html ObjectInputStream#resolveClass()] method to prevent arbitrary classes from being deserialized. This safe behavior can be wrapped in a library like [https://github.com/ikkisoft/SerialKiller SerialKiller].&lt;br /&gt;
* Implementation: Use a safe replacement for the generic readObject() method as seen [http://www.contrastsecurity.com/security-influencers/java-serialization-vulnerability-threatens-millions-of-applications here]. Note that this addresses &amp;quot;billion laughs&amp;quot; type attacks by checking input length and number of objects deserialized.&lt;br /&gt;
* Implementation: Use a Java agent to override the internals of ObjectInputStream to prevent exploitation of known dangerous types as seen in [https://github.com/Contrast-Security-OSS/contrast-rO0 rO0] and [https://github.com/kantega/notsoserial NotSoSerial]&lt;br /&gt;
* Implementation: Participate in the reimplementation of ObjectInputStream; Atomic Serialization is designed with security in mind from the outset, while maintaining Object Serial Form compatibility; note this is not a drop in replacement like those above, but likely to be the most secure option.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* [http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/#websphere FoxGlove vulnerability announcement]&lt;br /&gt;
* [http://wouter.coekaerts.be/2011/amf-arbitrary-code-execution JFrame DoS example by Wouter Coekaerts]&lt;br /&gt;
* [https://gist.github.com/coekie/a27cc406fc9f3dc7a70d HashSet Billion-Laughs Style DoS example by Wouter Coekaerts]&lt;br /&gt;
* [https://github.com/ikkisoft/SerialKiller Safe ObjectInputStream implementation that allows policy-based deserialization]&lt;br /&gt;
* [https://github.com/Contrast-Security-OSS/contrast-rO0 rO0, a Java agent that protects applications from deserialization attacks]&lt;br /&gt;
* [https://github.com/kantega/notsoserial NotSoSerial, a Java agent that protects applications from deserialization attacks]&lt;br /&gt;
* [https://github.com/pfirmstone/river-internet/tree/Input-validation-for-Serialization/src/org/apache/river/api/io Atomic Serialization using constructor with input validation, no circular references, Permission limited scope limited object cache and array length limits, with stream resets]&lt;br /&gt;
[[Category:Input Validation Vulnerability]]&lt;br /&gt;
*[http://www.slideshare.net/codewhitesec/java-deserialization-vulnerabilitesruhrseceditionv10 Java Deserialization Vulnerabilities - The Forgotten Bug Class (RuhrSec Edition)]&lt;br /&gt;
*[https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability.]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:OWASP ASDR Project]]&lt;br /&gt;
[[Category:Vulnerability]]&lt;br /&gt;
[[Category:Range and Type Error Vulnerability]]&lt;br /&gt;
[[Category:OWASP_CLASP_Project]]&lt;br /&gt;
[[Category:Code Snippet]]&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217369</id>
		<title>Implementacion De Firmas Digitales en Java</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Implementacion_De_Firmas_Digitales_en_Java&amp;diff=217369"/>
				<updated>2016-05-25T18:28:33Z</updated>
		
		<summary type="html">&lt;p&gt;Ledio5485: /* WARNING */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WARNING  ==&lt;br /&gt;
&lt;br /&gt;
Jim Manico recently brought to my attention this wiki page, the same who asked me to check exactly. In doing so, I noticed several errors and areas of weakness. Lately, I have the intention to revisit this page (hopefully with the help of one of the original owners), but I do not have time to do a full review at this time. Therefore, I will summarize the problems observed on this page and leaving you the decision to use or not, with these warnings.&lt;br /&gt;
&amp;lt;br /&amp;gt; &lt;br /&gt;
#First, this page does not describe &amp;quot;digital signatures&amp;quot;. Rather, it describes a concept known as &amp;quot;digital envelopes&amp;quot;, which is a scheme used with objects such as S / MIME. Digital signatures not only encrypt the actual message text, only encrypts the hash of the message text.&lt;br /&gt;
#UTF-8 should be used to convert between Java byte strings and arrays to ensure adequate portability across different operating systems.&lt;br /&gt;
#The certificate chain must always be validated. In this example, the certificate is self-signed, so this is not relevant and will not be true in the normal case. Furthermore, it should be noted that the self-signed, but acceptable for demonstration purposes certificates is considered a dubious practice for production, as it opens the door to spoofing attacks.&lt;br /&gt;
#[http://www.nist.gov/ NIST] now recommends using key size 2048 bits for RSA or DSA keys.&lt;br /&gt;
#There is a consistent use of weak algorithms. Here are some suggested replacements:&lt;br /&gt;
## Use &amp;quot;RSA/ECB/OAEPWithSHA1AndMGF1Padding&amp;quot; instead of &amp;quot;RSA/ECB/PKCS1Padding&amp;quot;.&lt;br /&gt;
## Use SHA1 (or better SHA256, SHA1 but at least) instead of MD5 for message digest.&lt;br /&gt;
## Use &amp;quot;SHA1withRSA&amp;quot; for the signature algorithm instead of &amp;quot;MD5withRSA&amp;quot;.&lt;br /&gt;
## When creating a symmetric encryption system to encrypt the message text, use &amp;quot;AES / CBC / PKCS5Padding&amp;quot; and choose an IV random for each text message instead of simply using &amp;quot;AES&amp;quot;, ending with &amp;quot;AES / ECB / PKCS5Padding &amp;quot;. ECB mode is extremely weak for a regular plain text. (OK for random bit encryption, however, is well used with RSA.) However, the use CBC and PKCS5Padding could make it vulnerable to &amp;quot;Padding Oracle&amp;quot; attacks, so caution is advised. You can use Encryptor 2.0 ESAPI 's to avoid it. (Note also, this part is the concept of &amp;quot;on digital&amp;quot;. If this page was really limited by &amp;quot;digital signatures&amp;quot; would not apply because it would be irrelevant.)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
I hope to get soonest, before cleaning this wiki page. Meanwhile, email me your questions.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
-Kevin Wall&lt;br /&gt;
&lt;br /&gt;
== Visión de conjunto ==&lt;br /&gt;
&lt;br /&gt;
Este artículo presenta un breve resumen de los conceptos involucrados con firmas digitales y proporciona ejemplos de código para la aplicación de firmas digitales en Java utilizando la Arquitectura de Java Cryptography.  &lt;br /&gt;
&lt;br /&gt;
=== ¿Qué es una firma digital?  ===&lt;br /&gt;
&lt;br /&gt;
Una firma digital es un concepto que ayuda a obtener el no repudio de origen (es decir, la Integridad del Origen) de datos. Al firmar digitalmente el documento, la persona que firma, asegura que él es el autor del documento o el mensaje firmado. &lt;br /&gt;
&lt;br /&gt;
=== Necesidad de Firma Digital  ===&lt;br /&gt;
&lt;br /&gt;
Durante la &amp;quot;E&amp;quot; revolución, fue una necesidad para la autenticación de críticas transacciones sobre todo en el mundo financiero. Si Alice se comprometió a transferir $ x para Bob, entonces tenía que haber una manera para que Bob se asegure de que:&lt;br /&gt;
&lt;br /&gt;
*Fue Alice quien realizó la transacción y no otra persona suplantando Alice (Autenticación).&lt;br /&gt;
*El monto acordado por Alice es $x (Integridad).&lt;br /&gt;
*Alicia no pudo discutir su declaración de transacción $x a Bob (No repudio de origen).&lt;br /&gt;
&lt;br /&gt;
Estas preocupaciones fueron tratadas con una solución conocida como firmas digitales. Más información de fondo sobre las firmas digitales se puede encontrar en [http://en.wikipedia.org/wiki/Digital_signature Wikipedia article] &lt;br /&gt;
&lt;br /&gt;
== Firmas digitales en Java utilizando JCA  ==&lt;br /&gt;
&lt;br /&gt;
La Arquitectura de Java Cryptography es un marco para el acceso y el desarrollo de la funcionalidad criptográfica para la plataforma Java. Un proveedor de JCA implementa las funcionalidades criptográficas como firmas digitales y compendios de mensajes. El proveedor predeterminado JCA en JDK 1.4.2 es SUN. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones de seguridad al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dos consideraciones principales de seguridad que se deben tener en cuenta al aplicar firmas digitales son:&lt;br /&gt;
&lt;br /&gt;
#Firma el mensaje y, a continuación cifrar el mensaje firmado.&lt;br /&gt;
#Firma el hash del mensaje en lugar del mensaje completo. &lt;br /&gt;
&lt;br /&gt;
=== Consideraciones sobre el rendimiento al implementar la firma digital  ===&lt;br /&gt;
&lt;br /&gt;
Dado que los algoritmos de cifrado asimétricos, como RSA, DSA son computacionalmente más lento que los algoritmos de cifrado simétricos como AES, es una buena práctica, cifrar el mensaje real que se transmite utilizando un algoritmo de clave simétrica y luego cifrar la clave que se utiliza en el algoritmo de clave simétrica utilizando un algoritmo de clave asimétrica. Por ejemplo: si se quiere transmitir el mensaje &amp;quot;Hola Mundo de Firmas Digitales&amp;quot;, entonces primero se cifra este mensaje con una clave simétrica, por ejemplo una clave AES de 128 bits como x7oFaHSPnWxEMiZE/0qYrg y luego se cifra esta clave con un algoritmo de clave asimétrica como RSA. &lt;br /&gt;
&lt;br /&gt;
== Algoritmo para implementar la firma digital utilizando el algoritmo RSA  ==&lt;br /&gt;
&lt;br /&gt;
El proveedor de la implementación en Java RSA tiene una limitación en que el cifrado se puede realizar sólo en los datos de longitud &amp;lt;= 117 bytes. Si los datos son de longitud &amp;gt; 117 bytes, se lanzaría un IllegalBlockSizeException: Los datos no debe tener más de 117 bytes ahí la simetría tiene que ser cifrados y luego firmados. &lt;br /&gt;
&lt;br /&gt;
El algoritmo RSA PKCS # 1 con relleno sólo puede cifrar los datos de tamaño k - 11 [http://www.rsa.com/rsalabs/node.asp?id=2125 1], donde k cuya longitud es de un octeto del módulo RSA y 11 es la cantidad de bytes utilizados por el relleno PCKS # 1 v1.5. Por lo tanto, si usamos una clave RSA de tamaño de 1024 bits, podríamos cifrar sólo 128 - 11 =&amp;gt; 117 bytes de datos. Hay dos opciones disponibles para cifrar los datos de tamaño de byte más grande.&lt;br /&gt;
&lt;br /&gt;
#Podríamos usar una clave RSA de longitud&amp;gt; 1024. Por ejemplo, si usamos 2048 bits, entonces podríamos cifrar 256-11 =&amp;gt; 245 bytes de datos. La desventaja de este enfoque es que no sería capaz de codificar los datos de tamaño&amp;gt; x bytes (en el ejemplo anterior x es 245).&lt;br /&gt;
#Analizar los datos de entrada en trozos de bytes de tamaño &amp;lt;117 y aplicar la encriptación en cada trozo. El código de ejemplo de este enfoque se puede encontrar aquí [http://www.aviransplace.com/2004/10/12/using-rsa-encryption-with-java/3/ here].&lt;br /&gt;
&lt;br /&gt;
Ambos enfoques podrían afectar al rendimiento ya que la clave RSA de mayor tamaño o un enfoque de &amp;quot;divide y vencerás&amp;quot; de bytes de entrada son computacionalmente costosa. &lt;br /&gt;
&lt;br /&gt;
=== Algoritmo  ===&lt;br /&gt;
&lt;br /&gt;
Con las anteriores consideraciones, el algoritmo siguiente puede ser usado para la implementación de la criptografía de clave pública en Java. &lt;br /&gt;
&lt;br /&gt;
#Cifrar el mensaje utilizando una clave simétrica&lt;br /&gt;
#Concatenar la clave simétrica + hash de clave simétrica + hash del mensaje.&lt;br /&gt;
#Cifrar la cadena concatenada con la clave pública de los receptores.&lt;br /&gt;
#Firmar los datos a transmitir (clave simétrica cifrada + Hash de la tecla + Hash del mensaje).&lt;br /&gt;
#Validar la firma. &lt;br /&gt;
#Descifrar el mensaje con la clave privada del receptor para obtener la clave simétrica. &lt;br /&gt;
#Validar la integridad de la clave utilizando el hash de la clave.  &lt;br /&gt;
#Descifrar el mensaje real usando la clave simétrica que se ha descifrado, se analiza y se comprueba la integridad. &lt;br /&gt;
#Calcular MessageDigest de datos.&lt;br /&gt;
#Validar si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original. &lt;br /&gt;
&lt;br /&gt;
=== Comandos para la generación de claves  ===&lt;br /&gt;
&lt;br /&gt;
prompt# keytool -genkey -alias testsender -keystore testkeystore.ks -keyalg RSA Enter keystore password: testpwd What is your first and last name? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Alice Sender&lt;br /&gt;
&lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  IT&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  LA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Alice Sender, OU = IT, O = ABC Inc, L = LA, ST = CA, C = EE.UU. correcto?  &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testsender&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  send123&lt;br /&gt;
&lt;br /&gt;
prompt # keytool -genkey -alias testrecv -keystore testkeystore.ks -keyalg RSA Introduzca la contraseña del almacén de claves: testpwd &lt;br /&gt;
¿Cuál es su nombre y apellido?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  Bob Receiver&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de la unidad organizativa?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  HR&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su organización? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  ABC Inc&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su ciudad o localidad?&lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  SFO&lt;br /&gt;
&lt;br /&gt;
¿Cuál es el nombre de su estado o provincia? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  CA&lt;br /&gt;
&lt;br /&gt;
¿Qué es el código de país de dos letras para esta unidad? &lt;br /&gt;
&lt;br /&gt;
 [Unknown]:  US&lt;br /&gt;
&lt;br /&gt;
Es CN = Bob receptor, OU = HR, O = ABC Inc, L = SFO, ST = CA, C = EE.UU. correcto? &lt;br /&gt;
&lt;br /&gt;
 [no]:  y&lt;br /&gt;
&lt;br /&gt;
Introduzca la contraseña clave para &amp;amp;lt;testrecv&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
 (RETURN if same as keystore password):  recv123&lt;br /&gt;
&lt;br /&gt;
=== Ejemplo de Código  ===&lt;br /&gt;
&lt;br /&gt;
==== PublicKeyCryptography.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
import java.security.cert.*;&lt;br /&gt;
import javax.crypto.*;&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
import sun.misc.BASE64Decoder;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * &lt;br /&gt;
 * 1. Cifrar los datos utilizando una clave simétrica &lt;br /&gt;
 * 2. Cifrar la clave simétrica con la clave pública Receptores &lt;br /&gt;
 * 3. Crear un resumen del mensaje de los datos a transmitir &lt;br /&gt;
 * 4. Firma el mensaje a transmitir &lt;br /&gt;
 * 5. Envíe los datos a través de un canal no seguro &lt;br /&gt;
 * 6. Validar la firma&lt;br /&gt;
 * 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica &lt;br /&gt;
 * 8. Descifrar los datos usando la clave simétrica &lt;br /&gt;
 * 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
 * 10.Valide si la síntesis del mensaje del texto descifrado coincide con el resumen de mensaje del mensaje original &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class PublicKeyCryptography {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		&lt;br /&gt;
	SymmetricEncrypt encryptUtil = new SymmetricEncrypt();&lt;br /&gt;
	String strDataToEncrypt = &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
	byte[] byteDataToTransmit = strDataToEncrypt.getBytes();&lt;br /&gt;
&lt;br /&gt;
	// Generación de un SecretKey para el cifrado simétrico&lt;br /&gt;
	SecretKey senderSecretKey = SymmetricEncrypt.getSecret();&lt;br /&gt;
	&lt;br /&gt;
	//1. Cifrar los datos utilizando una clave simétrica&lt;br /&gt;
	byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
	String strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	//2. Cifrar la clave simétrica con la clave pública &lt;br /&gt;
	try{&lt;br /&gt;
		// 2.1 Especifique el almacén de claves que se haya importado el certificado Receptores&lt;br /&gt;
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;
	char [] password = &amp;quot;testpwd&amp;quot;.toCharArray();&lt;br /&gt;
	java.io.FileInputStream fis = new java.io.FileInputStream(&amp;quot;/home/Joebi/workspace/OWASP_Crypto/org/owasp/crypto/testkeystore.ks&amp;quot;);&lt;br /&gt;
    ks.load(fis, password);&lt;br /&gt;
    fis.close();&lt;br /&gt;
    &lt;br /&gt;
	// 2.2 Creación de un certificado X509 del receptor&lt;br /&gt;
    X509Certificate recvcert&amp;amp;nbsp;;&lt;br /&gt;
    MessageDigest md = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvcert = (X509Certificate)ks.getCertificate(&amp;quot;testrecv&amp;quot;);&lt;br /&gt;
    // 2.3 Obtención de la llave pública de los certificados&lt;br /&gt;
    PublicKey pubKeyReceiver = recvcert.getPublicKey();&lt;br /&gt;
    &lt;br /&gt;
    // 2.4 Cifrado de la SecretKey con la clave pública Receptores&lt;br /&gt;
    byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);&lt;br /&gt;
        &lt;br /&gt;
    // 3. Crear un resumen del mensaje de los datos a transmitir&lt;br /&gt;
    md.update(byteDataToTransmit);&lt;br /&gt;
	byte byteMDofDataToTransmit[] = md.digest();&lt;br /&gt;
	&lt;br /&gt;
	String strMDofDataToTransmit = new String();&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteMDofDataToTransmit.length; i++){&lt;br /&gt;
		strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	&lt;br /&gt;
    // 3.1 Mensaje que se Firmado = clave secreta cifrada + MAC de los datos a transmitir&lt;br /&gt;
	String strMsgToSign = strSenbyteEncryptWithPublicKey + &amp;quot;|&amp;quot; + strMDofDataToTransmit;&lt;br /&gt;
    &lt;br /&gt;
    // 4. Firma el mensaje&lt;br /&gt;
    // 4.1 Obtener la clave privada del remitente desde el almacén de claves, proporcionando la contraseña establecida para la llave privada mientras se crea las llaves usados.&lt;br /&gt;
	char[] keypassword = &amp;quot;send123&amp;quot;.toCharArray();&lt;br /&gt;
    Key myKey =  ks.getKey(&amp;quot;testsender&amp;quot;, keypassword);&lt;br /&gt;
    PrivateKey myPrivateKey = (PrivateKey)myKey;&lt;br /&gt;
    &lt;br /&gt;
    // 4.2 Firmar el mensaje&lt;br /&gt;
    Signature mySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    mySign.initSign(myPrivateKey);&lt;br /&gt;
    mySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    byte[] byteSignedData = mySign.sign();&lt;br /&gt;
        &lt;br /&gt;
	// 5. Los valores byteSignedData (la firma) y strMsgToSign (los datos que se firmó) se pueden enviar a través del receptor&lt;br /&gt;
	&lt;br /&gt;
	// 6. Validar la firma&lt;br /&gt;
    // 6.1 Extraer la clave pública de su certificado de remitentes&lt;br /&gt;
	X509Certificate sendercert&amp;amp;nbsp;;&lt;br /&gt;
	sendercert = (X509Certificate)ks.getCertificate(&amp;quot;testsender&amp;quot;);&lt;br /&gt;
    PublicKey pubKeySender = sendercert.getPublicKey();&lt;br /&gt;
    // 6.2 Verificar la Firma&lt;br /&gt;
    Signature myVerifySign = Signature.getInstance(&amp;quot;MD5withRSA&amp;quot;);&lt;br /&gt;
    myVerifySign.initVerify(pubKeySender);&lt;br /&gt;
    myVerifySign.update(strMsgToSign.getBytes());&lt;br /&gt;
    &lt;br /&gt;
    boolean verifySign = myVerifySign.verify(byteSignedData);&lt;br /&gt;
    if (verifySign == false)&lt;br /&gt;
    {&lt;br /&gt;
    	System.out.println(&amp;quot; Error in validating Signature &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    else&lt;br /&gt;
    	System.out.println(&amp;quot; Successfully validated Signature &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // 7. Descifrar el mensaje usando la llave privada Pets para obtener la clave simétrica&lt;br /&gt;
    char[] recvpassword = &amp;quot;recv123&amp;quot;.toCharArray();&lt;br /&gt;
    Key recvKey =  ks.getKey(&amp;quot;testrecv&amp;quot;, recvpassword);&lt;br /&gt;
    PrivateKey recvPrivateKey = (PrivateKey)recvKey;&lt;br /&gt;
    &lt;br /&gt;
    // Analizar el MessageDigest y el valor cifrado&lt;br /&gt;
    String strRecvSignedData = new String (byteSignedData);&lt;br /&gt;
    String[] strRecvSignedDataArray = new String [10];&lt;br /&gt;
    strRecvSignedDataArray = strMsgToSign.split(&amp;quot;|&amp;quot;);&lt;br /&gt;
    int intindexofsep = strMsgToSign.indexOf(&amp;quot;|&amp;quot;);&lt;br /&gt;
    String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);&lt;br /&gt;
    String strHashOfData = strMsgToSign.substring(intindexofsep+1);&lt;br /&gt;
&lt;br /&gt;
    // Descifrado para obtener la clave simétrica&lt;br /&gt;
    byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);&lt;br /&gt;
    byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // 8. Descifrar los datos usando la clave simétrica&lt;br /&gt;
    javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,&amp;quot;AES&amp;quot;);&lt;br /&gt;
    String strDecryptedText = new String(byteDecryptText);&lt;br /&gt;
    System.out.println(&amp;quot; Decrypted data is &amp;quot; +strDecryptedText);&lt;br /&gt;
    &lt;br /&gt;
    // 9. Calcule MessageDigest de datos + mensaje firmado&lt;br /&gt;
    MessageDigest recvmd = MessageDigest.getInstance(&amp;quot;MD5&amp;quot;);&lt;br /&gt;
    recvmd.update(byteDecryptText);&lt;br /&gt;
	byte byteHashOfRecvSignedData[] = recvmd.digest();&lt;br /&gt;
&lt;br /&gt;
	String strHashOfRecvSignedData = new String();&lt;br /&gt;
		&lt;br /&gt;
	for (int i = 0; i &amp;amp;lt; byteHashOfRecvSignedData.length; i++){&lt;br /&gt;
		strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] &amp;amp;amp; 0xFF)&amp;amp;nbsp;;&lt;br /&gt;
             }&lt;br /&gt;
	// 10. Validar si la síntesis del mensaje del texto coincide con el mensaje descifrado &lt;br /&gt;
   Digest of the Original Message&lt;br /&gt;
&lt;br /&gt;
	if (!strHashOfRecvSignedData.equals(strHashOfData))&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Message has been tampered &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	catch(Exception exp)&lt;br /&gt;
	{&lt;br /&gt;
		System.out.println(&amp;quot; Exception caught &amp;quot; + exp);&lt;br /&gt;
		exp.printStackTrace();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
==== SymmetricEncrypt.java  ====&lt;br /&gt;
&amp;lt;pre&amp;gt;package org.owasp.crypto;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.KeyGenerator;&lt;br /&gt;
import javax.crypto.SecretKey;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import java.security.Key;&lt;br /&gt;
&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
&lt;br /&gt;
import sun.misc.BASE64Encoder;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Joe Prasanna Kumar&lt;br /&gt;
 * Este programa ofrece las funcionalidades criptográficas siguientes&lt;br /&gt;
 * 1. Cifrado con AES&lt;br /&gt;
 * 2. El descifrado con AES&lt;br /&gt;
 *&lt;br /&gt;
 * Algoritmo de alto nivel:&lt;br /&gt;
 * 1. Generar una clave DES (especificar el tamaño de la clave durante esta fase)&lt;br /&gt;
 * 2. Cree el Cipher&lt;br /&gt;
 * 3. Para cifrar: Inicializar el cifrado para el cifrado&lt;br /&gt;
 * 4. Para descifrar: Inicializar el cifrado para descifrar&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
public class SymmetricEncrypt {&lt;br /&gt;
			&lt;br /&gt;
		String strDataToEncrypt = new String();&lt;br /&gt;
		String strCipherText = new String();&lt;br /&gt;
		String strDecryptedText = new String();&lt;br /&gt;
		static KeyGenerator keyGen;&lt;br /&gt;
		private static String strHexVal = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		public static SecretKey getSecret(){&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 1. Generación de una clave AES mediante keygenerator &lt;br /&gt;
		 *  		Inicializa el tamaño de clave de 128&lt;br /&gt;
		 * &lt;br /&gt;
		 */&lt;br /&gt;
			&lt;br /&gt;
			try{&lt;br /&gt;
				keyGen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;);&lt;br /&gt;
				keyGen.init(128);&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
					&lt;br /&gt;
			catch(Exception exp)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; Exception inside constructor &amp;quot; +exp);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			SecretKey secretKey = keyGen.generateKey();&lt;br /&gt;
			return secretKey;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 2. Crear un sistema de cifrado mediante la especificación de los siguientes parámetros &lt;br /&gt;
		 * 			a. Nombre del algoritmo - aquí es AES &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteCipherText = new byte[200];&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
			Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 3. Inicialice el cifrado para el cifrado &lt;br /&gt;
		 */&lt;br /&gt;
			if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
				}&lt;br /&gt;
				else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
				aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);&lt;br /&gt;
				} &lt;br /&gt;
				&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 4. Cifrar los datos&lt;br /&gt;
		 *  		1. Declarar / inicializar los datos. Aquí los datos son de tipo String &lt;br /&gt;
		 *  		2. Convertir el texto de entrada a Bytes&lt;br /&gt;
		 *  		3. Cifrado de los bytes, utilizando el método doFinal&lt;br /&gt;
		 */&lt;br /&gt;
		byteCipherText = aesCipher.doFinal(byteDataToEncrypt); &lt;br /&gt;
		strCipherText = new BASE64Encoder().encode(byteCipherText);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
				catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
					catch (InvalidKeyException invalidKey)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (BadPaddingException badPadding)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
					{&lt;br /&gt;
						System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
						illegalBlockSize.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					catch (Exception exp)&lt;br /&gt;
					{&lt;br /&gt;
						exp.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
		return byteCipherText;&lt;br /&gt;
		}&lt;br /&gt;
		/**&lt;br /&gt;
		 *  Paso 5. Descifrar los datos&lt;br /&gt;
		 *  		1. Inicialice el cifrado para descifrar &lt;br /&gt;
		 *  		2. Descifrar los bytes cifrados utilizando el método doFinal &lt;br /&gt;
		 */&lt;br /&gt;
		&lt;br /&gt;
		public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {&lt;br /&gt;
			byte[] byteDecryptedText = new byte[200];&lt;br /&gt;
						&lt;br /&gt;
			try{	&lt;br /&gt;
		Cipher aesCipher = Cipher.getInstance(Algorithm);&lt;br /&gt;
		if(Algorithm.equals(&amp;quot;AES&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());&lt;br /&gt;
		}&lt;br /&gt;
		else if(Algorithm.equals(&amp;quot;RSA/ECB/PKCS1Padding&amp;quot;)){&lt;br /&gt;
		aesCipher.init(Cipher.DECRYPT_MODE,secretKey);&lt;br /&gt;
		} &lt;br /&gt;
		&lt;br /&gt;
		byteDecryptedText = aesCipher.doFinal(byteCipherText);&lt;br /&gt;
		strDecryptedText = new String(byteDecryptedText);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		catch (NoSuchAlgorithmException noSuchAlgo)&lt;br /&gt;
		{&lt;br /&gt;
			System.out.println(&amp;quot; No Such Algorithm exists &amp;quot; + noSuchAlgo);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
			catch (NoSuchPaddingException noSuchPad)&lt;br /&gt;
			{&lt;br /&gt;
				System.out.println(&amp;quot; No Such Padding exists &amp;quot; + noSuchPad);&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
				catch (InvalidKeyException invalidKey)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Key &amp;quot; + invalidKey);&lt;br /&gt;
					invalidKey.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (BadPaddingException badPadding)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Bad Padding &amp;quot; + badPadding);&lt;br /&gt;
					badPadding.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (IllegalBlockSizeException illegalBlockSize)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Illegal Block Size &amp;quot; + illegalBlockSize);&lt;br /&gt;
					illegalBlockSize.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				catch (InvalidAlgorithmParameterException invalidParam)&lt;br /&gt;
				{&lt;br /&gt;
					System.out.println(&amp;quot; Invalid Parameter &amp;quot; + invalidParam);&lt;br /&gt;
				}&lt;br /&gt;
	&lt;br /&gt;
		return byteDecryptedText;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		public static byte[] convertStringToByteArray(String strInput) {&lt;br /&gt;
			strInput = strInput.toLowerCase();&lt;br /&gt;
			byte[] byteConverted = new byte[(strInput.length() + 1) / 2];&lt;br /&gt;
			int j = 0;&lt;br /&gt;
			int interimVal;&lt;br /&gt;
			int nibble = -1;&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; strInput.length(); ++i) {&lt;br /&gt;
				interimVal = strHexVal.indexOf(strInput.charAt(i));&lt;br /&gt;
				if (interimVal &amp;amp;gt;= 0) {&lt;br /&gt;
					if (nibble &amp;amp;lt; 0) {&lt;br /&gt;
						nibble = interimVal;&lt;br /&gt;
					} else {&lt;br /&gt;
						byteConverted[j++] = (byte) ((nibble &amp;amp;lt;&amp;amp;lt; 4) + interimVal);&lt;br /&gt;
						nibble = -1;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (nibble &amp;amp;gt;= 0) {&lt;br /&gt;
				byteConverted[j++] = (byte) (nibble &amp;amp;lt;&amp;amp;lt; 4);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (j &amp;amp;lt; byteConverted.length) {&lt;br /&gt;
				byte[] byteTemp = new byte[j];&lt;br /&gt;
				System.arraycopy(byteConverted, 0, byteTemp, 0, j);&lt;br /&gt;
				byteConverted = byteTemp;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return byteConverted;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		public static String convertByteArrayToString(byte[] block) {&lt;br /&gt;
			StringBuffer buf = new StringBuffer();&lt;br /&gt;
&lt;br /&gt;
			for (int i = 0; i &amp;amp;lt; block.length; ++i) {&lt;br /&gt;
				buf.append(strHexVal.charAt((block[i] &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; 4) &amp;amp;amp; 0xf));&lt;br /&gt;
				buf.append(strHexVal.charAt(block[i] &amp;amp;amp; 0xf));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			return buf.toString();&lt;br /&gt;
		}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Referencias  ==&lt;br /&gt;
&lt;br /&gt;
#Computer Security Arts and Science – Matt Bishop &lt;br /&gt;
#Core Security Patterns – Christopher Steele, Ray Lai and Ramesh Nagappan&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Aplicaciones en Ambientes Libres'''&lt;br /&gt;
&lt;br /&gt;
 '''Tutor:'''  Ing. Tito Armas&lt;br /&gt;
&lt;br /&gt;
 '''Traductoroas:''' Bravo Maria Jose y Portilla Maria Fernanda 2012&lt;/div&gt;</summary>
		<author><name>Ledio5485</name></author>	</entry>

	</feed>