700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

时间:2021-04-10 13:33:07

相关推荐

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了。但这两种算法使用环境有差异,刚好互补。

一、MD5算法

首先MD5是不可逆的,只能加密而不能解密。比如明文是yanzi1225627,得到MD5加密后的字符串是:14F2AE15259E2C276A095E7394DA0CA9 但不能由后面一大串倒推出yanzi1225627.因此可以用来存储用户输入的密码在服务器上。现在下载文件校验文件是否中途被篡改也是用的它,原理参见:/forgotaboutgirl/article/details/7258109无论在Android上还是pc上用java实现MD5都比较容易,因为java已经把它做到了java.security.MessageDigest里。下面是一个MD5Util.java类:

[java]view plaincopyprint? <spanstyle="font-family:ComicSansMS;font-size:18px;">packageorg.md5.util;importjava.security.MessageDigest;publicclassMD5Util{publicfinalstaticStringgetMD5String(Strings){charhexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};try{byte[]btInput=s.getBytes();//获得MD5摘要算法的MessageDigest对象MessageDigestmdInst=MessageDigest.getInstance("MD5");//使用指定的字节更新摘要mdInst.update(btInput);//获得密文byte[]md=mdInst.digest();//把密文转换成十六进制的字符串形式intj=md.length;charstr[]=newchar[j*2];intk=0;for(inti=0;i<j;i++){bytebyte0=md[i];str[k++]=hexDigits[byte0>>>4&0xf];str[k++]=hexDigits[byte0&0xf];}returnnewString(str);}catch(Exceptione){e.printStackTrace();returnnull;}}}</span>

通过下面两行代码调用:

/************************************MD5加密测试*****************************/

String srcString = "yanzi1225627";

System.out.println("MD5加密后 = " + MD5Util.getMD5String(srcString));

二、RSA加密

RSA是可逆的,一个字符串可以经rsa加密后,经加密后的字符串传到对端如服务器上,再进行解密即可。前提是服务器知道解密的私钥,当然这个私钥最好不要再网络传输。RSA算法描述中需要以下几个变量:

1、p和q 是不相等的,足够大的两个质数。 p和q是保密的

2、n = p*q n是公开的

3、f(n) = (p-1)*(q-1)

4、e 是和f(n)互质的质数

5、计算参数d

6、经过上面5步计算得到公钥KU=(e,n) 私钥KR=(d,n)

下面两篇文章对此有清晰的描述:

/view/e53fbe36a32d7375a417801b.html

/-06-24/118958531.html

下面是java实现RSAUtil.java类:

[java]view plaincopyprint? <spanstyle="font-family:ComicSansMS;font-size:18px;">packageorg.rsa.util;importjavax.crypto.Cipher;importjava.security.*;importjava.security.spec.RSAPublicKeySpec;importjava.security.spec.RSAPrivateKeySpec;importjava.security.spec.InvalidKeySpecException;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.io.*;importjava.math.BigInteger;/***RSA工具类。提供加密,解密,生成密钥对等方法。*需要到下载bcprov-jdk14-123.jar。*RSA加密原理概述*RSA的安全性依赖于大数的分解,公钥和私钥都是两个大素数(大于100的十进制位)的函数。*据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积*===================================================================*(该算法的安全性未得到理论的证明)*===================================================================*密钥的产生:*1.选择两个大素数p,q,计算n=p*q;*2.随机选择加密密钥e,要求e和(p-1)*(q-1)互质*3.利用Euclid算法计算解密密钥d,使其满足e*d=1(mod(p-1)*(q-1))(其中n,d也要互质)*4:至此得出公钥为(n,e)私钥为(n,d)*===================================================================*加解密方法:*1.首先将要加密的信息m(二进制表示)分成等长的数据块m1,m2,...,mi块长s(尽可能大),其中2^s<n*2:对应的密文是:ci=mi^e(modn)*3:解密时作如下计算:mi=ci^d(modn)*===================================================================*RSA速度*由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论是软件还是硬件实现。*速度一直是RSA的缺陷。一般来说只用于少量数据加密。*文件名:RSAUtil.java<br>*@author董利伟<br>*版本:<br>*描述:<br>*创建时间:-9-23下午09:58:16<br>*文件描述:<br>*修改者:<br>*修改日期:<br>*修改描述:<br>*/publicclassRSAUtil{//密钥对privateKeyPairkeyPair=null;/***初始化密钥对*/publicRSAUtil(){try{this.keyPair=this.generateKeyPair();}catch(Exceptione){e.printStackTrace();}}/***生成密钥对*@returnKeyPair*@throwsException*/privateKeyPairgenerateKeyPair()throwsException{try{KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());//这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低finalintKEY_SIZE=1024;keyPairGen.initialize(KEY_SIZE,newSecureRandom());KeyPairkeyPair=keyPairGen.genKeyPair();returnkeyPair;}catch(Exceptione){thrownewException(e.getMessage());}}/***生成公钥*@parammodulus*@parampublicExponent*@returnRSAPublicKey*@throwsException*/privateRSAPublicKeygenerateRSAPublicKey(byte[]modulus,byte[]publicExponent)throwsException{KeyFactorykeyFac=null;try{keyFac=KeyFactory.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());}catch(NoSuchAlgorithmExceptionex){thrownewException(ex.getMessage());}RSAPublicKeySpecpubKeySpec=newRSAPublicKeySpec(newBigInteger(modulus),newBigInteger(publicExponent));try{return(RSAPublicKey)keyFac.generatePublic(pubKeySpec);}catch(InvalidKeySpecExceptionex){thrownewException(ex.getMessage());}}/***生成私钥*@parammodulus*@paramprivateExponent*@returnRSAPrivateKey*@throwsException*/privateRSAPrivateKeygenerateRSAPrivateKey(byte[]modulus,byte[]privateExponent)throwsException{KeyFactorykeyFac=null;try{keyFac=KeyFactory.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());}catch(NoSuchAlgorithmExceptionex){thrownewException(ex.getMessage());}RSAPrivateKeySpecpriKeySpec=newRSAPrivateKeySpec(newBigInteger(modulus),newBigInteger(privateExponent));try{return(RSAPrivateKey)keyFac.generatePrivate(priKeySpec);}catch(InvalidKeySpecExceptionex){thrownewException(ex.getMessage());}}/***加密*@paramkey加密的密钥*@paramdata待加密的明文数据*@return加密后的数据*@throwsException*/publicbyte[]encrypt(Keykey,byte[]data)throwsException{try{Ciphercipher=Cipher.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());cipher.init(Cipher.ENCRYPT_MODE,key);//获得加密块大小,如:加密前数据为128个byte,而key_size=1024加密块大小为127byte,加密后为128个byte;//因此共有2个加密块,第一个127byte第二个为1个byteintblockSize=cipher.getBlockSize();intoutputSize=cipher.getOutputSize(data.length);//获得加密块加密后块大小intleavedSize=data.length%blockSize;intblocksSize=leavedSize!=0?data.length/blockSize+1:data.length/blockSize;byte[]raw=newbyte[outputSize*blocksSize];inti=0;while(data.length-i*blockSize>0){if(data.length-i*blockSize>blockSize)cipher.doFinal(data,i*blockSize,blockSize,raw,i*outputSize);elsecipher.doFinal(data,i*blockSize,data.length-i*blockSize,raw,i*outputSize);//这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中//,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。i++;}returnraw;}catch(Exceptione){thrownewException(e.getMessage());}}/***解密*@paramkey解密的密钥*@paramraw已经加密的数据*@return解密后的明文*@throwsException*/publicbyte[]decrypt(Keykey,byte[]raw)throwsException{try{Ciphercipher=Cipher.getInstance("RSA",neworg.bouncycastle.jce.provider.BouncyCastleProvider());cipher.init(cipher.DECRYPT_MODE,key);intblockSize=cipher.getBlockSize();ByteArrayOutputStreambout=newByteArrayOutputStream(64);intj=0;while(raw.length-j*blockSize>0){bout.write(cipher.doFinal(raw,j*blockSize,blockSize));j++;}returnbout.toByteArray();}catch(Exceptione){thrownewException(e.getMessage());}}/***返回公钥*@return*@throwsException*/publicRSAPublicKeygetRSAPublicKey()throwsException{//获取公钥RSAPublicKeypubKey=(RSAPublicKey)keyPair.getPublic();//获取公钥系数(字节数组形式)byte[]pubModBytes=pubKey.getModulus().toByteArray();//返回公钥公用指数(字节数组形式)byte[]pubPubExpBytes=pubKey.getPublicExponent().toByteArray();//生成公钥RSAPublicKeyrecoveryPubKey=this.generateRSAPublicKey(pubModBytes,pubPubExpBytes);returnrecoveryPubKey;}/***获取私钥*@return*@throwsException*/publicRSAPrivateKeygetRSAPrivateKey()throwsException{//获取私钥RSAPrivateKeypriKey=(RSAPrivateKey)keyPair.getPrivate();//返回私钥系数(字节数组形式)byte[]priModBytes=priKey.getModulus().toByteArray();//返回私钥专用指数(字节数组形式)byte[]priPriExpBytes=priKey.getPrivateExponent().toByteArray();//生成私钥RSAPrivateKeyrecoveryPriKey=this.generateRSAPrivateKey(priModBytes,priPriExpBytes);returnrecoveryPriKey;}}</span>

测试代码:

/****************************RSA加密解密测试********************************/

try {

RSAUtil rsa = new RSAUtil();

String str = "yanzi1225627";

RSAPublicKey pubKey = rsa.getRSAPublicKey();

RSAPrivateKey priKey = rsa.getRSAPrivateKey();

byte[] enRsaBytes = rsa.encrypt(pubKey,str.getBytes());

String enRsaStr = new String(enRsaBytes, "UTF-8");

System.out.println("加密后==" + enRsaStr);

System.out.println("解密后==" + new String(rsa.decrypt(priKey, rsa.encrypt(pubKey,str.getBytes()))));

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

下面是执行结果:

加密后==s?ko?1@lo????BJ?iE???1Ux?Kx&??=??n

O? ?l?>?????2r?y??8v- \A??`????r?t3?-3y?hjL?M??Se?Z???????~?"??e??XZ?苜?

解密后==yanzi1225627

上面代码需要用到一个包rsa.jar,下载链接及上面的测试代码我已打包,下载链接见下:

/detail/yanzi1225627/7382263

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。