Java me 如何在j2me CLDC应用程序中写入/读取RSA公钥和私钥
我正在开发一个j2me应用程序,它使用RSA和AES算法的混合。RSA密钥用于安全密钥交换,而AES用于消息加密。应用程序需要生成RSA密钥并将其存储/写入移动设备上的安全位置,并在需要时从设备读取。我使用下面的代码(摘自Michael Juntao的《企业j2me》一书)生成了密钥 在同一本书中,以下代码用于编写键。但是,我发现这里使用的FileOutputStream()类在CLDC中不受支持(仅在CDC和J2SE中受支持) 请帮助我如何最好地开始写和读RSA密钥 我使用了RecordStore(RMS)来存储密钥。Recordstore中可以存储三种数据类型:String、byte和Int。但是,RSA密钥的组件是BigInteger数据类型。因此,我获得了每个关键组件的“字符串”表示/等价物,如下所示:Java me 如何在j2me CLDC应用程序中写入/读取RSA公钥和私钥,java-me,persistent-storage,Java Me,Persistent Storage,我正在开发一个j2me应用程序,它使用RSA和AES算法的混合。RSA密钥用于安全密钥交换,而AES用于消息加密。应用程序需要生成RSA密钥并将其存储/写入移动设备上的安全位置,并在需要时从设备读取。我使用下面的代码(摘自Michael Juntao的《企业j2me》一书)生成了密钥 在同一本书中,以下代码用于编写键。但是,我发现这里使用的FileOutputStream()类在CLDC中不受支持(仅在CDC和J2SE中受支持) 请帮助我如何最好地开始写和读RSA密钥 我使用了RecordSto
//method for serializing the key components
public void SerializeRSAKeyPair()
{
BigInteger mod = RSAprivKey.getModulus();
String mods = mod.toString();// converts to String representation
BigInteger privExp = RSAprivKey.getExponent();
String privExps = privExp.toString(); // converts to String representation
BigInteger pubExp = RSAprivKey.getPublicExponent();
String pubExps = pubExp.toString();//..same
BigInteger dp = RSAprivKey.getDP();
String dps = dp.toString();
BigInteger dq = RSAprivKey.getDQ();
String dqs = dq.toString();
BigInteger p = RSAprivKey.getP();
String ps = p.toString();
BigInteger q = RSAprivKey.getQ();
String qs = q.toString();
BigInteger qInv = RSAprivKey.getQInv();
String qInvs = qInv.toString();
String [] RSAstrings = {mods, privExps,pubExps,dps,dqs, ps,qs,qInvs};
// all combined to a String array
writeStream(strings);
}
//Write the String array RSAKeyPairStore Recordstore
public void writeStream(String[] sData)
{
try
{
// Write data into an internal byte array
ByteArrayOutputStream strmBytes =
new ByteArrayOutputStream();
// Write Java data types into the above byte array
DataOutputStream strmDataType =
new DataOutputStream(strmBytes);
byte[] record;
for (int i = 0; i < sData.length; i++)
{
// Write Java String data
strmDataType.writeUTF(sData[i]);
// Clear any buffered data
strmDataType.flush();
// Get stream data into byte array and write record
record = strmBytes.toByteArray();
RSAKeyPairStore.addRecord(record, 0, record.length);
strmBytes.reset();
}
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
private void db(String str)
{
System.err.println("Msg: " + str);
}
// To read the keys create separate methods for reading Public Keys and private keys
//the record store using streams.
public void readRSApublic()
{
try
{
byte[] recData = new byte[100];
ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read data from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);
// since only the modulus and public exponents are required for computing RSA Public keys,
//we read record 1 and 3 as follows
RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);// use this to confirm that its equal to the BigInteger/equivalent below
BigInteger RSAmod = new BigInteger(mod);
//System.out.println ("RSAmod = " + RSAmod);
//use this confirm its equal to the string equivalent above
strmBytes.reset();
RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
//System.out.println ("pubExp = " + pubExp);
BigInteger RSApubExp = new BigInteger(pubExp);
//System.out.println ("RSApubExp = " + RSApubExp);
strmBytes.reset();
//then reconstruct the public key from the retrieved records
newRSApubKey = new RSAKeyParameters(false, RSAmod, RSApubExp);
// then use the key for the purpose you want e.g for encryption of data
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
// when you need the private key, do the same; Retrieve (as strings)all the components that makes up the private key namely; and then convert them to BigInteger equivalents and then reconstruct as above
public void readRSAprivate()
{
try
{
byte[] recData = new byte[500];
ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read Java data types from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);
RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);
BigInteger RSAmod = new BigInteger(mod);
strmBytes.reset();
RSAKeyPairStore.getRecord(2, recData, 0);
String privExp = strmDataType.readUTF();
//System.out.println ("privExp = " + privExp);
BigInteger RSAprivExp = new BigInteger(privExp);
//System.out.println ("RSAprivExp = " + RSAprivExp);
strmBytes.reset();
RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
BigInteger RSApubExp = new BigInteger(pubExp);
strmBytes.reset();
RSAKeyPairStore.getRecord(4, recData, 0);
String dps = strmDataType.readUTF();
BigInteger RSAdp = new BigInteger(dps);
strmBytes.reset();
RSAKeyPairStore.getRecord(5, recData, 0);
String dqs = strmDataType.readUTF();
BigInteger RSAdq = new BigInteger(dqs);
strmBytes.reset();
RSAKeyPairStore.getRecord(6, recData, 0);
String p = strmDataType.readUTF();
BigInteger RSAp = new BigInteger(p);
strmBytes.reset();
RSAKeyPairStore.getRecord(7, recData, 0);
String q = strmDataType.readUTF();
BigInteger RSAq = new BigInteger(q);
strmBytes.reset();
RSAKeyPairStore.getRecord(8, recData, 0);
String qInv = strmDataType.readUTF();
BigInteger RSAqInv = new BigInteger(qInv);
strmBytes.reset();
// then use the key for the purpose you want e.g for Signing
newRSAprivKey = new RSAPrivateCrtKeyParameters(RSAmod, RSAprivExp, RSApubExp, RSAp,
RSAq, RSAdp, RSAdq, RSAqInv);
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
//序列化关键组件的方法
public void序列化密钥对()
{
biginger mod=RSAprivKey.getmodule();
字符串mods=mod.toString();//转换为字符串表示形式
BigInteger privExp=RSAprivKey.getExponent();
字符串privExps=privExp.toString();//转换为字符串表示形式
BigInteger=RSAprivKey.getPublicExponent();
字符串pubExps=pubExp.toString();/…相同
biginger dp=RSAprivKey.getDP();
字符串dps=dp.toString();
biginger dq=RSAprivKey.getDQ();
字符串dqs=dq.toString();
biginger p=RSAprivKey.getP();
字符串ps=p.toString();
biginger q=RSAprivKey.getQ();
字符串qs=q.toString();
biginger qInv=RSAprivKey.getQInv();
字符串qInvs=qInv.toString();
String[]RSAstrings={mods,privExps,pubExps,dps,dqs,ps,qs,qInvs};
//全部合并为字符串数组
writeStream(字符串);
}
//写入字符串数组RSAKeyPairStore Recordstore
public void writeStream(字符串[]sData)
{
尝试
{
//将数据写入内部字节数组
ByteArrayOutputStream标准字节=
新的ByteArrayOutputStream();
//将Java数据类型写入上述字节数组
DataOutputStream strmDataType=
新数据输出流(标准字节);
字节[]记录;
对于(int i=0;iBigInteger mod = RSAprivKey.getModulus();
out = new FileOutputStream(outdir + "RSAmod.dat");
out.write(mod.toByteArray());
out.flush(); out.close();
BigInteger privExp = RSAprivKey.getExponent();
out = new FileOutputStream(outdir + "RSAprivExp.dat");
out.write(privExp.toByteArray());
out.flush(); out.close();
pubExp = RSAprivKey.getPublicExponent();
if ( !pubExp.equals(new BigInteger("10001", 16)) )
throw new Exception("wrong public exponent");
out = new FileOutputStream(outdir + "RSApubExp.dat");
out.write(pubExp.toByteArray());
out.flush(); out.close();
BigInteger dp = RSAprivKey.getDP();
out = new FileOutputStream(outdir + "RSAdp.dat");
out.write(dp.toByteArray());
out.flush(); out.close();
BigInteger dq = RSAprivKey.getDQ();
out = new FileOutputStream(outdir + "RSAdq.dat");
out.write(dq.toByteArray());
out.flush(); out.close();
BigInteger p = RSAprivKey.getP();
out = new FileOutputStream(outdir + "RSAp.dat");
out.write(p.toByteArray());
out.flush(); out.close();
BigInteger q = RSAprivKey.getQ();
out = new FileOutputStream(outdir + "RSAq.dat");
out.write(q.toByteArray());
out.flush(); out.close();
BigInteger qInv = RSAprivKey.getQInv();
out = new FileOutputStream(outdir + "RSAqInv.dat");
out.write(qInv.toByteArray());
out.flush(); out.close();
//method for serializing the key components
public void SerializeRSAKeyPair()
{
BigInteger mod = RSAprivKey.getModulus();
String mods = mod.toString();// converts to String representation
BigInteger privExp = RSAprivKey.getExponent();
String privExps = privExp.toString(); // converts to String representation
BigInteger pubExp = RSAprivKey.getPublicExponent();
String pubExps = pubExp.toString();//..same
BigInteger dp = RSAprivKey.getDP();
String dps = dp.toString();
BigInteger dq = RSAprivKey.getDQ();
String dqs = dq.toString();
BigInteger p = RSAprivKey.getP();
String ps = p.toString();
BigInteger q = RSAprivKey.getQ();
String qs = q.toString();
BigInteger qInv = RSAprivKey.getQInv();
String qInvs = qInv.toString();
String [] RSAstrings = {mods, privExps,pubExps,dps,dqs, ps,qs,qInvs};
// all combined to a String array
writeStream(strings);
}
//Write the String array RSAKeyPairStore Recordstore
public void writeStream(String[] sData)
{
try
{
// Write data into an internal byte array
ByteArrayOutputStream strmBytes =
new ByteArrayOutputStream();
// Write Java data types into the above byte array
DataOutputStream strmDataType =
new DataOutputStream(strmBytes);
byte[] record;
for (int i = 0; i < sData.length; i++)
{
// Write Java String data
strmDataType.writeUTF(sData[i]);
// Clear any buffered data
strmDataType.flush();
// Get stream data into byte array and write record
record = strmBytes.toByteArray();
RSAKeyPairStore.addRecord(record, 0, record.length);
strmBytes.reset();
}
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
private void db(String str)
{
System.err.println("Msg: " + str);
}
// To read the keys create separate methods for reading Public Keys and private keys
//the record store using streams.
public void readRSApublic()
{
try
{
byte[] recData = new byte[100];
ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read data from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);
// since only the modulus and public exponents are required for computing RSA Public keys,
//we read record 1 and 3 as follows
RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);// use this to confirm that its equal to the BigInteger/equivalent below
BigInteger RSAmod = new BigInteger(mod);
//System.out.println ("RSAmod = " + RSAmod);
//use this confirm its equal to the string equivalent above
strmBytes.reset();
RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
//System.out.println ("pubExp = " + pubExp);
BigInteger RSApubExp = new BigInteger(pubExp);
//System.out.println ("RSApubExp = " + RSApubExp);
strmBytes.reset();
//then reconstruct the public key from the retrieved records
newRSApubKey = new RSAKeyParameters(false, RSAmod, RSApubExp);
// then use the key for the purpose you want e.g for encryption of data
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
// when you need the private key, do the same; Retrieve (as strings)all the components that makes up the private key namely; and then convert them to BigInteger equivalents and then reconstruct as above
public void readRSAprivate()
{
try
{
byte[] recData = new byte[500];
ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read Java data types from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);
RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);
BigInteger RSAmod = new BigInteger(mod);
strmBytes.reset();
RSAKeyPairStore.getRecord(2, recData, 0);
String privExp = strmDataType.readUTF();
//System.out.println ("privExp = " + privExp);
BigInteger RSAprivExp = new BigInteger(privExp);
//System.out.println ("RSAprivExp = " + RSAprivExp);
strmBytes.reset();
RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
BigInteger RSApubExp = new BigInteger(pubExp);
strmBytes.reset();
RSAKeyPairStore.getRecord(4, recData, 0);
String dps = strmDataType.readUTF();
BigInteger RSAdp = new BigInteger(dps);
strmBytes.reset();
RSAKeyPairStore.getRecord(5, recData, 0);
String dqs = strmDataType.readUTF();
BigInteger RSAdq = new BigInteger(dqs);
strmBytes.reset();
RSAKeyPairStore.getRecord(6, recData, 0);
String p = strmDataType.readUTF();
BigInteger RSAp = new BigInteger(p);
strmBytes.reset();
RSAKeyPairStore.getRecord(7, recData, 0);
String q = strmDataType.readUTF();
BigInteger RSAq = new BigInteger(q);
strmBytes.reset();
RSAKeyPairStore.getRecord(8, recData, 0);
String qInv = strmDataType.readUTF();
BigInteger RSAqInv = new BigInteger(qInv);
strmBytes.reset();
// then use the key for the purpose you want e.g for Signing
newRSAprivKey = new RSAPrivateCrtKeyParameters(RSAmod, RSAprivExp, RSApubExp, RSAp,
RSAq, RSAdp, RSAdq, RSAqInv);
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}