想用rn做个RSA(非对称加密)登录
基本流程就是在服务端生成RSA后,将“公钥”发到客户端,然后客户端用“公钥”加密信息发送到服务端,服务务端用私钥解密。
过程不复杂,问题在于,nodejs和rn都准备用js做RSA加密,本来想用node-rsa做的,可是搞不懂它怎么设置公钥加密
于是直接做node-rsa的基础库http://www-cs-students.stanford.edu/~tjw/jsbn/,简单封装了下做了个demo
客户端:
'use strict'; const React = require('react-native'); var url="192.168.1.103:8082" var RSAClient= require('./rsa-client');//客户端rsa加密 var _publicKey = new RSAClient(); //初始化“公钥” fetch('http://'+url+'/RSA') .then((response) => response.json()) .then( (ret) => { _publicKey.setPublic(ret.n, ret.e); } ).done(); //“公钥”加密,加密后的数据是hex编码比较长,所以转成base64 var encrypt=function(val){ var hex2b64 = require('./base64').hex2b64; return hex2b64(_publicKey.encrypt(val)); }; var login=function(data,doSuccess,doError){ fetch('http://'+url+'/login', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(data) }) .then(function(response) {return response.json();}) .then( function(resData){ doSuccess(resData); } ) .done(); }; var { View, Text, TextInput, StyleSheet, TouchableOpacity } = React; var Index = React.createClass({ getInitialState: function() { return { userName: "", passWord: "", encrypted:"" }; }, render:function() { return ( <View style={{borderColor:'#FA6778', justifyContent: 'center', flex:1, }}> <View style={{flex:1}}> <Text>encrypted = {this.state.encrypted}</Text> <Text>decrypted = {this.state.decrypted}</Text> </View> <View style={{flex:1.2}}> <View style={styles.singleLine}> <TextInput autoCapitalize="none" style={{flex:1, fontSize: 16,padding: 6,borderWidth: 0,textDecorationLine :'none'}} placeholder="User Name" onChangeText={(text) => { this.setState({userName:text});}} value={this.state.userName} /> </View> <View style={styles.singleLine}> <TextInput placeholder="PassWord" password ={true} style={{flex:1, fontSize: 16,padding: 6,borderWidth: 0,textDecorationLine :'none'}} onChangeText={(text) => { this.setState({passWord:text});}} value={this.state.passWord} /> </View> <TouchableOpacity style={styles.btn} onPress={ ()=> { let _pwd= encrypt(this.state.passWord); login( {userName:this.state.userName,passWord:_pwd}, (retJson) => { if(1==retJson.loginState){ this.setState({encrypted:retJson.encrypted,decrypted:retJson.decrypted}); } }); } }> <Text style={{ flex: 1, fontSize: 18, alignSelf: 'center', }}>OK</Text> </TouchableOpacity> </View> <View style={{flex:1}}></View> </View>); } }); var styles = StyleSheet.create({ btn: { alignSelf: 'stretch', alignItems: 'center', justifyContent: 'center', backgroundColor: '#3333FF', height: 40, borderRadius: 5, margin: 8, padding: 8, }, singleLine: { height: 40, borderWidth: 1, borderRadius: 5, borderColor: 'lightblue', margin: 15, }, }); module.exports=Index;
服务端:
var Router= require('router'), http = require('http'), fs = require('fs'), path = require('path'); /* module.id module.filename module.loaded module.parent module.children console.log(module); */ var router = Router() //**************RSA BEGIN************************ var RSAService = require('./RSAService'); var _key = new RSAService.rsaKey(); _key.generate(384,"10001"); /* console.log("Generating RSA Key..."); console.log("_key e"); console.log(_key.e.toString(16)); console.log("_key n"); console.log(_key.n.toString(16)); console.log("_key d"); console.log(_key.d.toString(16)); console.log("_key p"); console.log(_key.p.toString(16)); console.log("_key q"); console.log(_key.q.toString(16)); console.log("_key dmp1"); console.log(_key.dmp1.toString(16)); console.log("_key dmq1"); console.log(_key.dmq1.toString(16)); console.log("_key coeff"); console.log(_key.coeff.toString(16)); */ var hex2b64 = RSAService.hex2b64; var b64tohex= RSAService.b64tohex; var publicKey={e:_key.e.toString(16),n:_key.n.toString(16)};//公钥 router.get('/RSA', function (req, res) { res.setHeader('Content-Type', 'application/json; charset=utf-8') res.write(JSON.stringify(publicKey)); res.end(); }); router.post('/login', function (req, res) { var _cnt=0; var body = ''; req.on('data', function (data) { body += data; _cnt++; // Too much POST data, kill the connection! // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB if (body.length > 1e6) request.connection.destroy(); }); req.on('end', function () { // var post = qs.parse(body); // use post['blah'], etc. var _state=1,_pwd=''; var _pObj= JSON.parse(body); if(_pObj.passWord){ try{ _pwd =_key.decrypt(b64tohex(_pObj.passWord));// key.decrypt(_pObj.passWord, 'utf8'); console.log('_pwd: ', _pwd); }catch(er){ console.log(er); _state=0; _pwd="ERROR"; } res.write(JSON.stringify({loginState:_state,encrypted:_pObj.passWord,decrypted:_pwd})); } res.end(); console.log('time='+Date.now()); }); }); var server = http.createServer( function(req, res) { console.log(req.url); router(req, res, function(req,res){}); }); server.listen( 8082, '::', function () { console.log('http server listening on port 8082 time='+Date.now() ); });
客户端/服务端 RSA文件http://files.cnblogs.com/files/Grart/rsa.rar