700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结

Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结

时间:2020-05-04 09:52:26

相关推荐

Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结

(1)commons-codec包简介 包含一些通用的编码解码算法。包括一些语音编码器,Hex,Base64.MD5

一、mons-codec包

commons-codec包可以从apache下载,最新版是1.3

不可逆算法

1.MD5

<!---->Stringstr="abc";

DigestUtils.md5Hex(str);

附.net生成MD5的方法,生成内容跟java一致:

<!---->Stringstr="abc";

FormsAuthentication.HashPasswordForStoringInConfigFile(str,"MD5");

自己写的MD5算法:

import java.security.MessageDigest;

public class MD5Util {

public final static String getMD5String(String s) {

char hexDigits[] = { '0', '1', '2', '3', '4',

'5', '6', '7', '8', '9',

'A', 'B', 'C', 'D', 'E', 'F' };

try {

byte[] btInput = s.getBytes();

//获得MD5摘要算法的 MessageDigest 对象

MessageDigest mdInst = MessageDigest.getInstance("MD5");

//使用指定的字节更新摘要

mdInst.update(btInput);

//获得密文

byte[] md = mdInst.digest();

//把密文转换成十六进制的字符串形式

int j = md.length;

char str[] = new char[j * 2];

int k = 0;

for (int i = 0; i < j; i++) {

byte byte0 = md[i];

str[k++] = hexDigits[byte0 >>> 4 & 0xf];

str[k++] = hexDigits[byte0 & 0xf];

}

return new String(str);

}

catch (Exception e) {

e.printStackTrace();

return null;

}

}

}

2.SHA1

<!---->Stringstr="abc";

DigestUtils.shaHex(str);

附.net生成SHA1的方式,生成内容跟java一致:

<!---->Stringstr="abc";

FormsAuthentication.HashPasswordForStoringInConfigFile(str,"SHA1");

可逆算法

常规加密解密算法:BASE64

加密

<!---->Stringstr="abc"; // abc为要加密的字符串

byte[]b=Base64.encodeBase64(str.getBytes(),true);

System.out.println(newString(b));

解密

<!---->Stringstr="YWJj"; //YWJj为要解密的字符串

byte[]b=Base64.decodeBase64(str.getBytes());

System.out.println(newString(b));

二、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个byte intblockSize=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); else cipher.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

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