怎样对邮件正文分段加密及解密

--------php 源码-------------

$mailcont = "邮件正文………超过1024字节………邮件正文";
$crtpath = "/usr/nc-home/webpost/mailbox/d00/1/y/u/yushuai.niu/.user/certkey/wxd.crt";
exec("chmod 777 {$crtpath}");
$fp = fopen($crtpath, "r");
$crt = fread($fp, 8192);
fclose($fp);
$pubKey = openssl_get_publickey($crt);
//从证书中解析公钥
$keyData = openssl_pkey_get_details($pubKey);
$blocks = str_split($mailcont, 1000);
foreach ($blocks as $block) {
//公钥加密
if (!openssl_public_encrypt($block, $chrtext, $keyData['key'])) {
echo "<br/>" . openssl_error_string() . "<br/>";
}
$chrtext .= $chrtext;
}
echo "chrtext-->>>$chrtext<br/>";

$keypath = "/usr/nc-home/webpost/mailbox/d00/1/y/u/yushuai.niu/.user/secretkey/wxd.key";
exec("chmod 777 {$keypath}");
$fp = fopen($keypath, "r");
$key = fread($fp, 8192);
fclose($fp);
$cipher = openssl_pkey_get_private($key);
openssl_private_decrypt($chrtext, $dcyCont, $cipher);
echo "dcyCont-->>>$dcyCont<br/>";


-------------------错误响应----------------
error:0906D06C:PEM routines:PEM_read_bio:no start line

error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size

chrtext-->>>叔��騈蕈50后帞 氧(蘗因T繥r'Um淤€<�/閥f貸f�,�� %vY筊諬�粁`樇昀�煲� �枹��妎5傊(䦟-|Q@祯�)Q耂o瑂駾鉌t饧k[F0鴎叔��騈蕈50后帞 氧(蘗因T繥r'Um淤€<�/閥f貸f�,�� %vY筊諬�粁`樇昀�煲� �枹��妎5傊(䦟-|Q@祯�)Q耂o瑂駾鉌t饧k[F0鴎
dcyCont-->>>
--------------------
证书及私钥 绝对正确,只是openssl_public_encrypt()函数貌似不能循环加密?求解!!!
...全文
690 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这里补充一下,public_encrypt()函数中加入:
$chrtext = base64_encode($chrtext);
和private_decrypt()函数中加入:
$chrtext = base64_decode($chrtext);
不然加密数据在传输的过程中会丢失数据。
黄袍披身 2012-02-23
  • 打赏
  • 举报
回复
恭喜解决问题,同时也感谢你将解决后的代码分享给大家.
  • 打赏
  • 举报
回复
经过各种途径终于将该问题解决,非常感谢各位楼主及热心人士的帮忙!详解如下:

/** 公钥加密
* $crtpath 证书[绝对路径/证书名称]
* $mailcont 需要加密的内容
* $sign 分界符
* 需要 splitCN(),subCNchar(),is_utf8()三个函数
**/
function public_encrypt($crtpath, $mailcont, $sign = false) {
$fp = fopen($crtpath, "r");
$crt = fread($fp, 8192);
fclose($fp);
$pubKey = openssl_get_publickey($crt);
//从证书中解析公钥
$keyData = openssl_pkey_get_details($pubKey);
$blocks = $this->splitCN($mailcont, 0, 30);
$chrtext = null;
$encodes = array ();
foreach ($blocks as $n => $block) {
if (!openssl_public_encrypt($block, $chrtext, $keyData['key'])) {
echo "<br/>" . openssl_error_string() . "<br/>";
}
$encodes[] = $chrtext;
}
$chrtext = implode($sign, $encodes);
return $chrtext;
}

/** 私钥解密
* $keypath 私钥[绝对路径/私钥名称]
* $chrtext 需要解密的内容
* $sign 分界符
**/
function private_decrypt($keypath, $chrtext, $sign = false) {
$fp = fopen($keypath, "r");
$key = fread($fp, 8192);
fclose($fp);
$cipher = openssl_pkey_get_private($key);
$decodes = explode($sign, $chrtext);
$strnull = "";
$dcyCont = null;
foreach ($decodes as $n => $decode) {
openssl_private_decrypt($decode, $dcyCont, $cipher);
$strnull .= $dcyCont;
}
return $strnull;
}

/** 截取汉字 *
* $str 要截取的字符串
* $start 截取的起始位置
* $length 要截取的长度
* $charset 字符串编码
**/
function subCNchar($str, $start = 0, $length, $charset = "utf-8") {
if (strlen($str) <= $length)
return $str;

$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);

$slice = join("", array_slice($match[0], $start, $length));

return $slice;
}

/** 将字符串按规定长度分段截取并放入数组
* $cont 要处理的字符串
* $n 起始位置
* $subnum 限定的截取长度(字节)
**/
function splitCN($cont, $n = 0, $subnum) {
//$len = strlen($cont) / 3;
for ($i = $n; $i < strlen($cont); $i += $subnum) {
$res = $this->subCNchar($cont, $i, $subnum);
if (!empty ($res)) {
$arrr[] = $res;
}
}
return $arrr;
}
//------------具体调用-------------
/**************** 公钥加密 ****************/
$crtpath = "/path/xxx.crt";
//邮件正文段落连接符
$sign = "%^&_&^%";
//加密
$chrtext = $referen->public_encrypt($crtpath,$mailcont,$sign);
//-------------私钥解密------------
$keyname = "xxx.key";
$keypath = "/path/" . $keyname;
$dcyCont = $referen->private_decrypt($keypath,$phcont,$sign);
黄袍披身 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dmtnewtons 的回复:]

引用 3 楼 phpnewnew 的回复:
可是你仍然分得太大.

//按每段100字节分
$blocks = str_split($mailcont, 100);
这也太多段了吧,
chrtext-->>>綔 峲]昖蝚觶Tf)飩峍浰G㖞峚�宴嵢展y5^.╝C\%耴>vgL5�<果F3-碑#tm@吴8� �ZV(巈g�#�.楗�>贞艼雺貫8|蘰�$�/)W……
[/Quote]

有汉字的话这么切会不会一个汉字给切成了两块?导致无法解密? 你可以用英文试一下的,如果英文没问题那就证实我的想法是正确的.可以先将汉字做一个编码,然后在解码后再进行还原,不过这增加了字符的长度...

不好意思,我跟你一样对这个openssl_public_encrypt 很陌生,所以也就没有实例提供了.
liu510817387 2012-02-22
  • 打赏
  • 举报
回复
str_split($mailcont, 100); 你有可能把中文字符串给拆开了!
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 phpnewnew 的回复:]
可是你仍然分得太大.
[/Quote]
//按每段100字节分
$blocks = str_split($mailcont, 100);
这也太多段了吧,
chrtext-->>>綔 峲]昖蝚觶Tf)飩峍浰G㖞峚�宴嵢展y5^.╝C\%耴>vgL5�<果F3-碑#tm@吴8� �ZV(巈g�#�.楗�>贞艼雺貫8|蘰�$�/)W穑=�綔 峲]昖蝚觶Tf)飩峍浰G㖞峚�宴嵢展y5^.╝C\%耴>vgL5�<果F3-碑#tm@吴8� �ZV(巈g�#�.楗�>贞艼雺貫8|蘰�$�/)W穑=�
dcyCont-->>>
而且也没有解密出来啊,
您能不能给个分段加密和对应解密的实例呢?感激不尽啊。
coder 2012-02-22
  • 打赏
  • 举报
回复
加密是大事,但是别的邮件服务商不会解你的密吧。纠结中。加还是不加
黄袍披身 2012-02-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dmtnewtons 的回复:]

引用 1 楼 phpnewnew 的回复:

文件太大了,把要加密的内容弄成一部分一部分进行加密

晕,楼上哥们,我知道啊,要不也不会把邮件内容分段放入数组中再循环加密了。求正解!
[/Quote]

可是你仍然分得太大.
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 phpnewnew 的回复:]

文件太大了,把要加密的内容弄成一部分一部分进行加密
[/Quote]
晕,楼上哥们,我知道啊,要不也不会把邮件内容分段放入数组中再循环加密了。求正解!
黄袍披身 2012-02-22
  • 打赏
  • 举报
回复
文件太大了,把要加密的内容弄成一部分一部分进行加密
  • 打赏
  • 举报
回复
我有试过了,中英文是有差别但是不大,都接不出来……
----------php code---------

$mailcont = "邮件正文………超过1024字节………邮件正文";
$mailcont_english = "mail content………more than 1024 KB………mail content";
$crtpath = "/usr/nc-home/webpost/mailbox/d00/1/y/u/yushuai.niu/.user/certkey/wxd.crt";
exec("chmod 777 {$crtpath}");
$fp = fopen($crtpath, "r");
$crt = fread($fp, 8192);
fclose($fp);
$pubKey = openssl_get_publickey($crt);
//从证书中解析公钥
$keyData = openssl_pkey_get_details($pubKey);
$blocks = str_split($mailcont, 100);
$decodes = array();
foreach ($blocks as $block) {
//公钥加密
if (!openssl_public_encrypt($block, $chrtext, $keyData['key'])) {
echo "<br/>" . openssl_error_string() . "<br/>";
}
$decodes[] = $chrtext;
$chrtext .= $chrtext;
}
echo "chrtext-->>>$chrtext<br/>";

$keypath = "/usr/nc-home/webpost/mailbox/d00/1/y/u/yushuai.niu/.user/secretkey/wxd.key";
exec("chmod 777 {$keypath}");
$fp = fopen($keypath, "r");
$key = fread($fp, 8192);
fclose($fp);
$cipher = openssl_pkey_get_private($key);
foreach($decodes as $decode){
openssl_private_decrypt($decode, $dcyCont, $cipher);
$dcyCont .= $dcyCont;
}

echo "dcyCont-->>>$dcyCont<br/>";

---------中文结果--------
chrtext-->>>€-扉�弻Eげ竄黹���蘂蔁^柮��入X勝>~稍礘eD@:�弿瀭歀�/詣劷�勔:I飤虄�Xo.mX-"/0奌m涫濍 ld犔倚b��<摸ィ��#汻€-扉�弻Eげ竄黹���蘂蔁^柮��入X勝>~稍礘eD@:�弿瀭歀�/詣劷�勔:I飤虄�Xo.mX-"/0奌m涫濍 ld犔倚b��<摸ィ��#汻
dcyCont-->>>岄叆鑴嗕笉鐨紝鏄崈鐧惧勾鏉ヤ汉浠枩鐖辩殑椋熷搧銆倢閰ヨ剢涓嶇毊锛屾槸鍗冪櫨骞存潵浜轰滑鍠滅埍鐨勯鍝併€�
---------英文结果--------
chrtext-->>>!�騅�|戟蚝_瑧媁yr鲟=Hm櫖�騈螨\7◣<伂<槼=,o@嘃�奭活湀旵以嚓��dQ �#6緲0eI�0礹N釫�-V浡恿F.N霠瞯怵k�瘉)岾!�騅�|戟蚝_瑧媁yr鲟=Hm櫖�騈螨\7◣<伂<槼=,o@嘃�奭活湀旵以嚓��dQ �#6緲0eI�0礹N釫�-V浡恿F.N霠瞯怵k�瘉)岾
dcyCont-->>> Linux RedHat 9 Linux RedHat 9
---------
求各位大侠正解!!!

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧