React Native + Nodejs 使用RSA加密登录

想用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

你可能感兴趣的:(React Native + Nodejs 使用RSA加密登录)